Merge "DrmSessionManager: use ndk resourcemanager"
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 3e8992a..62dbb5e 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -87,6 +87,7 @@
ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,
String cameraId,
String opPackageName,
+ @nullable String featureId,
int clientUid);
/**
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 9d40fd7..8eb030a 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -517,7 +517,7 @@
// No way to get package name from native.
// Send a zero length package name and let camera service figure it out from UID
binder::Status serviceRet = cs->connectDevice(
- callbacks, String16(cameraId), String16(""),
+ callbacks, String16(cameraId), String16(""), std::unique_ptr<String16>(),
hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
if (!serviceRet.isOk()) {
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index f07a1e6..9a18b10 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -361,7 +361,8 @@
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
- hardware::ICameraService::USE_CALLING_UID, /*out*/&device);
+ std::unique_ptr<String16>(), hardware::ICameraService::USE_CALLING_UID,
+ /*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
ASSERT_NE(nullptr, device.get());
device->disconnect();
@@ -403,7 +404,8 @@
{
SCOPED_TRACE("openNewDevice");
binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
- hardware::ICameraService::USE_CALLING_UID, /*out*/&device);
+ std::unique_ptr<String16>(), hardware::ICameraService::USE_CALLING_UID,
+ /*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
}
auto p = std::make_pair(callbacks, device);
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index 3a76591..a126a1d 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -19,8 +19,12 @@
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.0/IDrmFactory.h>
+#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.2/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/HidlSupport.h>
@@ -59,7 +63,7 @@
}
template <typename Hal, typename V>
-void MakeCryptoFactories(const uint8_t uuid[16], V &cryptoFactories) {
+void MakeHidlFactories(const uint8_t uuid[16], V &factories) {
sp<HServiceManager> serviceManager = HServiceManager::getService();
if (serviceManager == nullptr) {
ALOGE("Failed to get service manager");
@@ -72,7 +76,7 @@
if (factory != nullptr) {
ALOGI("found %s %s", Hal::descriptor, instance.c_str());
if (factory->isCryptoSchemeSupported(uuid)) {
- cryptoFactories.push_back(factory);
+ factories.push_back(factory);
}
}
}
@@ -94,6 +98,19 @@
return hidl_array<uint8_t, 16>(ptr);
}
+sp<::V1_0::IDrmPlugin> MakeDrmPlugin(const sp<::V1_0::IDrmFactory> &factory,
+ const uint8_t uuid[16], const char *appPackageName) {
+ sp<::V1_0::IDrmPlugin> plugin;
+ factory->createPlugin(toHidlArray16(uuid), hidl_string(appPackageName),
+ [&](::V1_0::Status status, const sp<::V1_0::IDrmPlugin> &hPlugin) {
+ if (status != ::V1_0::Status::OK) {
+ return;
+ }
+ plugin = hPlugin;
+ });
+ return plugin;
+}
+
sp<::V1_0::ICryptoPlugin> MakeCryptoPlugin(const sp<::V1_0::ICryptoFactory> &factory,
const uint8_t uuid[16], const void *initData,
size_t initDataSize) {
@@ -122,11 +139,28 @@
return MakeObject<CryptoHal>(pstatus);
}
+std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16]) {
+ std::vector<sp<::V1_0::IDrmFactory>> drmFactories;
+ MakeHidlFactories<::V1_0::IDrmFactory>(uuid, drmFactories);
+ MakeHidlFactories<::V1_1::IDrmFactory>(uuid, drmFactories);
+ MakeHidlFactories<::V1_2::IDrmFactory>(uuid, drmFactories);
+ return drmFactories;
+}
+
+std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
+ const char *appPackageName) {
+ std::vector<sp<::V1_0::IDrmPlugin>> plugins;
+ for (const auto &factory : MakeDrmFactories(uuid)) {
+ plugins.push_back(MakeDrmPlugin(factory, uuid, appPackageName));
+ }
+ return plugins;
+}
+
std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]) {
std::vector<sp<::V1_0::ICryptoFactory>> cryptoFactories;
- MakeCryptoFactories<::V1_0::ICryptoFactory>(uuid, cryptoFactories);
- MakeCryptoFactories<::V1_1::ICryptoFactory>(uuid, cryptoFactories);
- MakeCryptoFactories<::V1_2::ICryptoFactory>(uuid, cryptoFactories);
+ MakeHidlFactories<::V1_0::ICryptoFactory>(uuid, cryptoFactories);
+ MakeHidlFactories<::V1_1::ICryptoFactory>(uuid, cryptoFactories);
+ MakeHidlFactories<::V1_2::ICryptoFactory>(uuid, cryptoFactories);
return cryptoFactories;
}
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index ab6f645..3017274 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -18,6 +18,7 @@
#define ANDROID_DRMUTILS_H
#include <android/hardware/drm/1.0/ICryptoFactory.h>
+#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <utils/Errors.h> // for status_t
#include <utils/StrongPointer.h>
#include <binder/Parcel.h>
@@ -81,6 +82,11 @@
obj.writeInt32(hasNewUsableKey);
}
+std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16]);
+
+std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
+ const char *appPackageName);
+
std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]);
std::vector<sp<::V1_0::ICryptoPlugin>> MakeCryptoPlugins(const uint8_t uuid[16],
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 2d4e126..3568f7b 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -78,7 +78,8 @@
DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
.withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
.withFields({C2F(mSampleRate, value).oneOf({
- 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+ 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000,
+ 44100, 48000, 64000, 88200, 96000
})})
.withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
.build());
diff --git a/media/codec2/components/opus/C2SoftOpusDec.cpp b/media/codec2/components/opus/C2SoftOpusDec.cpp
index 6b6974f..b7c1556 100644
--- a/media/codec2/components/opus/C2SoftOpusDec.cpp
+++ b/media/codec2/components/opus/C2SoftOpusDec.cpp
@@ -62,7 +62,7 @@
addParameter(
DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
.withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
- .withFields({C2F(mSampleRate, value).equalTo(48000)})
+ .withFields({C2F(mSampleRate, value).inRange(8000, 48000)})
.withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
.build());
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.cpp b/media/codec2/components/xaac/C2SoftXaacDec.cpp
index 60ae93c..951d058 100644
--- a/media/codec2/components/xaac/C2SoftXaacDec.cpp
+++ b/media/codec2/components/xaac/C2SoftXaacDec.cpp
@@ -87,7 +87,8 @@
DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
.withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
.withFields({C2F(mSampleRate, value).oneOf({
- 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+ 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000,
+ 44100, 48000, 64000, 88200, 96000
})})
.withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
.build());
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index 4a9dc55..b96d29b 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -104,7 +104,7 @@
// public dependency for Codec 2.0 HAL service implementations
cc_defaults {
- name: "libcodec2-hidl-defaults",
+ name: "libcodec2-hidl-defaults@1.0",
defaults: ["libcodec2-impl-defaults"],
shared_libs: [
@@ -115,7 +115,7 @@
// public dependency for Codec 2.0 HAL client
cc_defaults {
- name: "libcodec2-hidl-client-defaults",
+ name: "libcodec2-hidl-client-defaults@1.0",
defaults: ["libcodec2-impl-defaults"],
shared_libs: [
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
index 8f21cf8..062dcd9 100644
--- a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
@@ -57,6 +57,12 @@
const sp<IInputSink>& sink,
connect_cb _hidl_cb) override;
+ InputSurface(
+ const std::shared_ptr<ParameterCache>& cache,
+ const std::shared_ptr<C2ReflectorHelper>& reflector,
+ const sp<HGraphicBufferProducer>& base,
+ const sp<GraphicBufferSource>& source);
+
protected:
class Interface;
@@ -68,19 +74,9 @@
std::shared_ptr<Interface> mIntf;
sp<CachedConfigurable> mConfigurable;
- InputSurface(
- const std::shared_ptr<ParameterCache>& cache,
- const std::shared_ptr<C2ReflectorHelper>& reflector,
- const sp<HGraphicBufferProducer>& base,
- const sp<GraphicBufferSource>& source);
-
virtual ~InputSurface() override = default;
-
- friend struct ComponentStore;
-
};
-
} // namespace utils
} // namespace V1_0
} // namespace c2
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
index 6469735..9656eb4 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
@@ -203,7 +203,7 @@
uint32_t mFramesReceived;
std::list<uint64_t> mFlushedIndices;
std::list<uint64_t> mTimestampUslist;
- ::android::List<outputMetaData> oBufferMetaData;
+ std::list<outputMetaData> oBufferMetaData;
C2BlockPool::local_id_t mBlockPoolId;
std::shared_ptr<C2BlockPool> mLinearPool;
@@ -594,7 +594,7 @@
int nSampleRate = bitStreamInfo[0];
int nChannels = bitStreamInfo[1];
std::list<uint64_t>::iterator itIn = mTimestampUslist.begin();
- android::List<outputMetaData>::iterator itOut = oBufferMetaData.begin();
+ auto itOut = oBufferMetaData.begin();
EXPECT_EQ(*itIn, itOut->timestampUs);
expTs = *itIn;
while (itOut != oBufferMetaData.end()) {
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
index d73b731..2f02913 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
@@ -20,6 +20,13 @@
#include "media_c2_hidl_test_common.h"
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+
+void ComponentTestEnvironment::registerTestServices() {
+ registerTestService<::android::hardware::media::c2::V1_0::
+ IComponentStore>();
+}
+
// Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
void testInputBuffer(
const std::shared_ptr<android::Codec2Client::Component>& component,
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
index db59e54..23e332a 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
@@ -17,32 +17,23 @@
#ifndef MEDIA_C2_HIDL_TEST_COMMON_H
#define MEDIA_C2_HIDL_TEST_COMMON_H
-#include <codec2/hidl/client.h>
-
-#include <android/hardware/media/c2/1.0/types.h>
-
#include <C2Component.h>
#include <C2Config.h>
+
+#include <codec2/hidl/client.h>
#include <getopt.h>
#include <hidl/HidlSupport.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/Mutexed.h>
-
-using namespace ::android::hardware::media::c2::V1_0;
-using namespace ::android::hardware::media::c2::V1_0::utils;
-
-using ::android::Mutexed;
-using ::android::hardware::Void;
-using ::android::hardware::Return;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-
#include <VtsHalHidlTargetTestEnvBase.h>
#define MAX_RETRY 20
#define TIME_OUT 400ms
#define MAX_INPUT_BUFFERS 8
+using ::android::hardware::Void;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+
/*
* Handle Callback functions onWorkDone(), onTripped(),
* onError(), onDeath(), onFramesRendered()
@@ -114,9 +105,7 @@
typedef ::testing::VtsHalHidlTargetTestEnvBase Super;
public:
- virtual void registerTestServices() override {
- registerTestService<IComponentStore>();
- }
+ virtual void registerTestServices() override;
ComponentTestEnvironment() : res("/data/local/tmp/media/") {}
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 be35b02..b737323 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -18,6 +18,14 @@
name: "VtsHalMediaC2V1_0TargetVideoDecTest",
defaults: ["VtsHalMediaC2V1_0Defaults"],
srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"],
+ header_libs: [
+ "libnativewindow_headers",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libgui",
+ "libutils",
+ ],
}
cc_test {
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 5e28750..9404aa8 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -28,6 +28,10 @@
#include <C2Debug.h>
#include <C2Buffer.h>
#include <C2BufferPriv.h>
+#include <gui/BufferQueue.h>
+#include <gui/IConsumerListener.h>
+#include <gui/IProducerListener.h>
+#include <system/window.h>
using android::C2AllocatorIon;
@@ -426,6 +430,48 @@
ASSERT_EQ(mDisableTest, false);
}
+TEST_F(Codec2VideoDecHidlTest, configureTunnel) {
+ description("Attempts to configure tunneling");
+ if (mDisableTest) return;
+ ALOGV("Checks if the component can be configured for tunneling");
+ native_handle_t* sidebandStream{};
+ c2_status_t err = mComponent->configureVideoTunnel(0, &sidebandStream);
+ if (err == C2_OMITTED) {
+ return;
+ }
+
+ using namespace android;
+ sp<NativeHandle> nativeHandle = NativeHandle::create(sidebandStream, true);
+
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ class DummyConsumerListener : public BnConsumerListener {
+ public:
+ DummyConsumerListener() : BnConsumerListener() {}
+ void onFrameAvailable(const BufferItem&) override {}
+ void onBuffersReleased() override {}
+ void onSidebandStreamChanged() override {}
+ };
+ consumer->consumerConnect(new DummyConsumerListener(), false);
+
+ class DummyProducerListener : public BnProducerListener {
+ public:
+ DummyProducerListener() : BnProducerListener() {}
+ virtual void onBufferReleased() override {}
+ virtual bool needsReleaseNotify() override { return false; }
+ virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
+ };
+ IGraphicBufferProducer::QueueBufferOutput qbo{};
+ producer->connect(new DummyProducerListener(),
+ NATIVE_WINDOW_API_MEDIA,
+ false,
+ &qbo);
+
+ ASSERT_EQ(producer->setSidebandStream(nativeHandle), NO_ERROR);
+}
+
class Codec2VideoDecDecodeTest
: public Codec2VideoDecHidlTest,
public ::testing::WithParamInterface<std::pair<int32_t, bool>> {
diff --git a/media/codec2/hidl/1.1/utils/Android.bp b/media/codec2/hidl/1.1/utils/Android.bp
new file mode 100644
index 0000000..d48197b
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/Android.bp
@@ -0,0 +1,154 @@
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-client-defaults instead
+cc_library {
+ name: "libcodec2_hidl_client@1.1",
+
+ defaults: ["hidl_defaults"],
+
+ srcs: [
+ "OutputBufferQueue.cpp",
+ "types.cpp",
+ ],
+
+ header_libs: [
+ "libcodec2_internal", // private
+ ],
+
+ shared_libs: [
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "libbase",
+ "libcodec2",
+ "libcodec2_hidl_client@1.0",
+ "libcodec2_vndk",
+ "libcutils",
+ "libgui",
+ "libhidlbase",
+ "liblog",
+ "libstagefright_bufferpool@2.0.1",
+ "libui",
+ "libutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ export_shared_lib_headers: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "libcodec2",
+ "libcodec2_hidl_client@1.0",
+ "libgui",
+ "libstagefright_bufferpool@2.0.1",
+ "libui",
+ ],
+}
+
+
+// DO NOT DEPEND ON THIS DIRECTLY
+// use libcodec2-hidl-defaults instead
+cc_library {
+ name: "libcodec2_hidl@1.1",
+ vendor_available: true,
+
+ defaults: ["hidl_defaults"],
+
+ srcs: [
+ "Component.cpp",
+ "ComponentInterface.cpp",
+ "ComponentStore.cpp",
+ "Configurable.cpp",
+ "InputBufferManager.cpp",
+ "InputSurface.cpp",
+ "InputSurfaceConnection.cpp",
+ "types.cpp",
+ ],
+
+ header_libs: [
+ "libbinder_headers",
+ "libsystem_headers",
+ "libcodec2_internal", // private
+ ],
+
+ shared_libs: [
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.media@1.0",
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "android.hardware.media.omx@1.0",
+ "libbase",
+ "libcodec2",
+ "libcodec2_hidl@1.0",
+ "libcodec2_vndk",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libstagefright_bufferpool@2.0.1",
+ "libstagefright_bufferqueue_helper",
+ "libui",
+ "libutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ export_shared_lib_headers: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "libcodec2",
+ "libcodec2_hidl@1.0",
+ "libcodec2_vndk",
+ "libhidlbase",
+ "libstagefright_bufferpool@2.0.1",
+ "libstagefright_bufferqueue_helper",
+ "libui",
+ ],
+}
+
+// public dependency for Codec 2.0 HAL service implementations
+cc_defaults {
+ name: "libcodec2-hidl-defaults@1.1",
+ defaults: ["libcodec2-impl-defaults"],
+
+ shared_libs: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "libcodec2_hidl@1.0",
+ "libcodec2_hidl@1.1",
+ "libcodec2_vndk",
+ "libhidlbase",
+ ],
+}
+
+// public dependency for Codec 2.0 HAL client
+cc_defaults {
+ name: "libcodec2-hidl-client-defaults@1.1",
+ defaults: ["libcodec2-impl-defaults"],
+
+ shared_libs: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "libcodec2_hidl_client@1.0",
+ "libcodec2_hidl_client@1.1",
+ "libcodec2_vndk",
+ "libhidlbase",
+ ],
+}
+
+// Alias to the latest "defaults" for Codec 2.0 HAL service implementations
+cc_defaults {
+ name: "libcodec2-hidl-defaults",
+ defaults: ["libcodec2-hidl-defaults@1.1"],
+}
+
+// Alias to the latest "defaults" for Codec 2.0 HAL client
+cc_defaults {
+ name: "libcodec2-hidl-client-defaults",
+ defaults: ["libcodec2-hidl-client-defaults@1.1"],
+}
diff --git a/media/codec2/hidl/1.1/utils/Component.cpp b/media/codec2/hidl/1.1/utils/Component.cpp
new file mode 100644
index 0000000..ed281e6
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/Component.cpp
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-Component@1.1"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.1/Component.h>
+#include <codec2/hidl/1.1/ComponentStore.h>
+#include <codec2/hidl/1.1/InputBufferManager.h>
+
+#include <hidl/HidlBinderSupport.h>
+#include <utils/Timers.h>
+
+#include <C2BqBufferPriv.h>
+#include <C2Debug.h>
+#include <C2PlatformSupport.h>
+
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using namespace ::android;
+
+// ComponentListener wrapper
+struct Component::Listener : public C2Component::Listener {
+
+ Listener(const sp<Component>& component) :
+ mComponent(component),
+ mListener(component->mListener) {
+ }
+
+ virtual void onError_nb(
+ std::weak_ptr<C2Component> /* c2component */,
+ uint32_t errorCode) override {
+ sp<IComponentListener> listener = mListener.promote();
+ if (listener) {
+ Return<void> transStatus = listener->onError(Status::OK, errorCode);
+ if (!transStatus.isOk()) {
+ LOG(ERROR) << "Component::Listener::onError_nb -- "
+ << "transaction failed.";
+ }
+ }
+ }
+
+ virtual void onTripped_nb(
+ std::weak_ptr<C2Component> /* c2component */,
+ std::vector<std::shared_ptr<C2SettingResult>> c2settingResult
+ ) override {
+ sp<IComponentListener> listener = mListener.promote();
+ if (listener) {
+ hidl_vec<SettingResult> settingResults(c2settingResult.size());
+ size_t ix = 0;
+ for (const std::shared_ptr<C2SettingResult> &c2result :
+ c2settingResult) {
+ if (c2result) {
+ if (!objcpy(&settingResults[ix++], *c2result)) {
+ break;
+ }
+ }
+ }
+ settingResults.resize(ix);
+ Return<void> transStatus = listener->onTripped(settingResults);
+ if (!transStatus.isOk()) {
+ LOG(ERROR) << "Component::Listener::onTripped_nb -- "
+ << "transaction failed.";
+ }
+ }
+ }
+
+ virtual void onWorkDone_nb(
+ std::weak_ptr<C2Component> /* c2component */,
+ std::list<std::unique_ptr<C2Work>> c2workItems) override {
+ for (const std::unique_ptr<C2Work>& work : c2workItems) {
+ if (work) {
+ if (work->worklets.empty()
+ || !work->worklets.back()
+ || (work->worklets.back()->output.flags &
+ C2FrameData::FLAG_INCOMPLETE) == 0) {
+ InputBufferManager::
+ unregisterFrameData(mListener, work->input);
+ }
+ }
+ }
+
+ sp<IComponentListener> listener = mListener.promote();
+ if (listener) {
+ WorkBundle workBundle;
+
+ sp<Component> strongComponent = mComponent.promote();
+ beginTransferBufferQueueBlocks(c2workItems, true);
+ if (!objcpy(&workBundle, c2workItems, strongComponent ?
+ &strongComponent->mBufferPoolSender : nullptr)) {
+ LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
+ << "received corrupted work items.";
+ endTransferBufferQueueBlocks(c2workItems, false, true);
+ return;
+ }
+ Return<void> transStatus = listener->onWorkDone(workBundle);
+ if (!transStatus.isOk()) {
+ LOG(ERROR) << "Component::Listener::onWorkDone_nb -- "
+ << "transaction failed.";
+ endTransferBufferQueueBlocks(c2workItems, false, true);
+ return;
+ }
+ endTransferBufferQueueBlocks(c2workItems, true, true);
+ }
+ }
+
+protected:
+ wp<Component> mComponent;
+ wp<IComponentListener> mListener;
+};
+
+// Component::Sink
+struct Component::Sink : public IInputSink {
+ std::shared_ptr<Component> mComponent;
+ sp<IConfigurable> mConfigurable;
+
+ virtual Return<Status> queue(const WorkBundle& workBundle) override {
+ return mComponent->queue(workBundle);
+ }
+
+ virtual Return<sp<IConfigurable>> getConfigurable() override {
+ return mConfigurable;
+ }
+
+ Sink(const std::shared_ptr<Component>& component);
+ virtual ~Sink() override;
+
+ // Process-wide map: Component::Sink -> C2Component.
+ static std::mutex sSink2ComponentMutex;
+ static std::map<IInputSink*, std::weak_ptr<C2Component>> sSink2Component;
+
+ static std::shared_ptr<C2Component> findLocalComponent(
+ const sp<IInputSink>& sink);
+};
+
+std::mutex
+ Component::Sink::sSink2ComponentMutex{};
+std::map<IInputSink*, std::weak_ptr<C2Component>>
+ Component::Sink::sSink2Component{};
+
+Component::Sink::Sink(const std::shared_ptr<Component>& component)
+ : mComponent{component},
+ mConfigurable{[&component]() -> sp<IConfigurable> {
+ Return<sp<IComponentInterface>> ret1 = component->getInterface();
+ if (!ret1.isOk()) {
+ LOG(ERROR) << "Sink::Sink -- component's transaction failed.";
+ return nullptr;
+ }
+ Return<sp<IConfigurable>> ret2 =
+ static_cast<sp<IComponentInterface>>(ret1)->
+ getConfigurable();
+ if (!ret2.isOk()) {
+ LOG(ERROR) << "Sink::Sink -- interface's transaction failed.";
+ return nullptr;
+ }
+ return static_cast<sp<IConfigurable>>(ret2);
+ }()} {
+ std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+ sSink2Component.emplace(this, component->mComponent);
+}
+
+Component::Sink::~Sink() {
+ std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+ sSink2Component.erase(this);
+}
+
+std::shared_ptr<C2Component> Component::Sink::findLocalComponent(
+ const sp<IInputSink>& sink) {
+ std::lock_guard<std::mutex> lock(sSink2ComponentMutex);
+ auto i = sSink2Component.find(sink.get());
+ if (i == sSink2Component.end()) {
+ return nullptr;
+ }
+ return i->second.lock();
+}
+
+// Component
+Component::Component(
+ const std::shared_ptr<C2Component>& component,
+ const sp<IComponentListener>& listener,
+ const sp<ComponentStore>& store,
+ const sp<::android::hardware::media::bufferpool::V2_0::
+ IClientManager>& clientPoolManager)
+ : mComponent{component},
+ mInterface{new ComponentInterface(component->intf(),
+ store->getParameterCache())},
+ mListener{listener},
+ mStore{store},
+ mBufferPoolSender{clientPoolManager} {
+ // Retrieve supported parameters from store
+ // TODO: We could cache this per component/interface type
+ mInit = mInterface->status();
+}
+
+c2_status_t Component::status() const {
+ return mInit;
+}
+
+// Methods from ::android::hardware::media::c2::V1_1::IComponent
+Return<Status> Component::queue(const WorkBundle& workBundle) {
+ std::list<std::unique_ptr<C2Work>> c2works;
+
+ if (!objcpy(&c2works, workBundle)) {
+ return Status::CORRUPTED;
+ }
+
+ // Register input buffers.
+ for (const std::unique_ptr<C2Work>& work : c2works) {
+ if (work) {
+ InputBufferManager::
+ registerFrameData(mListener, work->input);
+ }
+ }
+
+ return static_cast<Status>(mComponent->queue_nb(&c2works));
+}
+
+Return<void> Component::flush(flush_cb _hidl_cb) {
+ std::list<std::unique_ptr<C2Work>> c2flushedWorks;
+ c2_status_t c2res = mComponent->flush_sm(
+ C2Component::FLUSH_COMPONENT,
+ &c2flushedWorks);
+
+ // Unregister input buffers.
+ for (const std::unique_ptr<C2Work>& work : c2flushedWorks) {
+ if (work) {
+ if (work->worklets.empty()
+ || !work->worklets.back()
+ || (work->worklets.back()->output.flags &
+ C2FrameData::FLAG_INCOMPLETE) == 0) {
+ InputBufferManager::
+ unregisterFrameData(mListener, work->input);
+ }
+ }
+ }
+
+ WorkBundle flushedWorkBundle;
+ Status res = static_cast<Status>(c2res);
+ beginTransferBufferQueueBlocks(c2flushedWorks, true);
+ if (c2res == C2_OK) {
+ if (!objcpy(&flushedWorkBundle, c2flushedWorks, &mBufferPoolSender)) {
+ res = Status::CORRUPTED;
+ }
+ }
+ _hidl_cb(res, flushedWorkBundle);
+ endTransferBufferQueueBlocks(c2flushedWorks, true, true);
+ return Void();
+}
+
+Return<Status> Component::drain(bool withEos) {
+ return static_cast<Status>(mComponent->drain_nb(withEos ?
+ C2Component::DRAIN_COMPONENT_WITH_EOS :
+ C2Component::DRAIN_COMPONENT_NO_EOS));
+}
+
+Return<Status> Component::setOutputSurface(
+ uint64_t blockPoolId,
+ const sp<HGraphicBufferProducer2>& surface) {
+ std::shared_ptr<C2BlockPool> pool;
+ GetCodec2BlockPool(blockPoolId, mComponent, &pool);
+ if (pool && pool->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
+ std::shared_ptr<C2BufferQueueBlockPool> bqPool =
+ std::static_pointer_cast<C2BufferQueueBlockPool>(pool);
+ C2BufferQueueBlockPool::OnRenderCallback cb =
+ [this](uint64_t producer, int32_t slot, int64_t nsecs) {
+ // TODO: batch this
+ hidl_vec<IComponentListener::RenderedFrame> rendered;
+ rendered.resize(1);
+ rendered[0] = { producer, slot, nsecs };
+ (void)mListener->onFramesRendered(rendered).isOk();
+ };
+ if (bqPool) {
+ bqPool->setRenderCallback(cb);
+ bqPool->configureProducer(surface);
+ }
+ }
+ return Status::OK;
+}
+
+Return<void> Component::connectToInputSurface(
+ const sp<IInputSurface>& inputSurface,
+ connectToInputSurface_cb _hidl_cb) {
+ Status status;
+ sp<IInputSurfaceConnection> connection;
+ auto transStatus = inputSurface->connect(
+ asInputSink(),
+ [&status, &connection](
+ Status s, const sp<IInputSurfaceConnection>& c) {
+ status = s;
+ connection = c;
+ }
+ );
+ _hidl_cb(status, connection);
+ return Void();
+}
+
+Return<void> Component::connectToOmxInputSurface(
+ const sp<HGraphicBufferProducer1>& producer,
+ const sp<::android::hardware::media::omx::V1_0::
+ IGraphicBufferSource>& source,
+ connectToOmxInputSurface_cb _hidl_cb) {
+ (void)producer;
+ (void)source;
+ (void)_hidl_cb;
+ return Void();
+}
+
+Return<Status> Component::disconnectFromInputSurface() {
+ // TODO implement
+ return Status::OK;
+}
+
+namespace /* unnamed */ {
+
+struct BlockPoolIntf : public ConfigurableC2Intf {
+ BlockPoolIntf(const std::shared_ptr<C2BlockPool>& pool)
+ : ConfigurableC2Intf{
+ "C2BlockPool:" +
+ (pool ? std::to_string(pool->getLocalId()) : "null"),
+ 0},
+ mPool{pool} {
+ }
+
+ virtual c2_status_t config(
+ const std::vector<C2Param*>& params,
+ c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures
+ ) override {
+ (void)params;
+ (void)mayBlock;
+ (void)failures;
+ return C2_OK;
+ }
+
+ virtual c2_status_t query(
+ const std::vector<C2Param::Index>& indices,
+ c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2Param>>* const params
+ ) const override {
+ (void)indices;
+ (void)mayBlock;
+ (void)params;
+ return C2_OK;
+ }
+
+ virtual c2_status_t querySupportedParams(
+ std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
+ ) const override {
+ (void)params;
+ return C2_OK;
+ }
+
+ virtual c2_status_t querySupportedValues(
+ std::vector<C2FieldSupportedValuesQuery>& fields,
+ c2_blocking_t mayBlock) const override {
+ (void)fields;
+ (void)mayBlock;
+ return C2_OK;
+ }
+
+protected:
+ std::shared_ptr<C2BlockPool> mPool;
+};
+
+} // unnamed namespace
+
+Return<void> Component::createBlockPool(
+ uint32_t allocatorId,
+ createBlockPool_cb _hidl_cb) {
+ std::shared_ptr<C2BlockPool> blockPool;
+ c2_status_t status = CreateCodec2BlockPool(
+ static_cast<C2PlatformAllocatorStore::id_t>(allocatorId),
+ mComponent,
+ &blockPool);
+ if (status != C2_OK) {
+ blockPool = nullptr;
+ }
+ if (blockPool) {
+ mBlockPoolsMutex.lock();
+ mBlockPools.emplace(blockPool->getLocalId(), blockPool);
+ mBlockPoolsMutex.unlock();
+ } else if (status == C2_OK) {
+ status = C2_CORRUPTED;
+ }
+
+ _hidl_cb(static_cast<Status>(status),
+ blockPool ? blockPool->getLocalId() : 0,
+ new CachedConfigurable(
+ std::make_unique<BlockPoolIntf>(blockPool)));
+ return Void();
+}
+
+Return<Status> Component::destroyBlockPool(uint64_t blockPoolId) {
+ std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+ return mBlockPools.erase(blockPoolId) == 1 ?
+ Status::OK : Status::CORRUPTED;
+}
+
+Return<Status> Component::start() {
+ return static_cast<Status>(mComponent->start());
+}
+
+Return<Status> Component::stop() {
+ InputBufferManager::unregisterFrameData(mListener);
+ return static_cast<Status>(mComponent->stop());
+}
+
+Return<Status> Component::reset() {
+ Status status = static_cast<Status>(mComponent->reset());
+ {
+ std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+ mBlockPools.clear();
+ }
+ InputBufferManager::unregisterFrameData(mListener);
+ return status;
+}
+
+Return<Status> Component::release() {
+ Status status = static_cast<Status>(mComponent->release());
+ {
+ std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
+ mBlockPools.clear();
+ }
+ InputBufferManager::unregisterFrameData(mListener);
+ return status;
+}
+
+Return<sp<IComponentInterface>> Component::getInterface() {
+ return sp<IComponentInterface>(mInterface);
+}
+
+Return<sp<IInputSink>> Component::asInputSink() {
+ std::lock_guard<std::mutex> lock(mSinkMutex);
+ if (!mSink) {
+ mSink = new Sink(shared_from_this());
+ }
+ return {mSink};
+}
+
+Return<void> Component::configureVideoTunnel(
+ uint32_t avSyncHwId, configureVideoTunnel_cb _hidl_cb) {
+ (void)avSyncHwId;
+ _hidl_cb(Status::OMITTED, hidl_handle{});
+ return Void();
+}
+
+std::shared_ptr<C2Component> Component::findLocalComponent(
+ const sp<IInputSink>& sink) {
+ return Component::Sink::findLocalComponent(sink);
+}
+
+void Component::initListener(const sp<Component>& self) {
+ std::shared_ptr<C2Component::Listener> c2listener =
+ std::make_shared<Listener>(self);
+ c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK);
+ if (res != C2_OK) {
+ mInit = res;
+ }
+}
+
+Component::~Component() {
+ InputBufferManager::unregisterFrameData(mListener);
+ mStore->reportComponentDeath(this);
+}
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/codec2/hidl/1.1/utils/ComponentInterface.cpp b/media/codec2/hidl/1.1/utils/ComponentInterface.cpp
new file mode 100644
index 0000000..ccc30fe
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/ComponentInterface.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/ComponentInterface.h>
diff --git a/media/codec2/hidl/1.1/utils/ComponentStore.cpp b/media/codec2/hidl/1.1/utils/ComponentStore.cpp
new file mode 100644
index 0000000..225cd09
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/ComponentStore.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Codec2-ComponentStore@1.1"
+#include <android-base/logging.h>
+
+#include <codec2/hidl/1.1/ComponentStore.h>
+#include <codec2/hidl/1.1/InputSurface.h>
+#include <codec2/hidl/1.1/types.h>
+
+#include <android-base/file.h>
+#include <media/stagefright/bqhelper/GraphicBufferSource.h>
+#include <utils/Errors.h>
+
+#include <C2PlatformSupport.h>
+#include <util/C2InterfaceHelper.h>
+
+#include <chrono>
+#include <ctime>
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using namespace ::android;
+using ::android::GraphicBufferSource;
+using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
+
+namespace /* unnamed */ {
+
+struct StoreIntf : public ConfigurableC2Intf {
+ StoreIntf(const std::shared_ptr<C2ComponentStore>& store)
+ : ConfigurableC2Intf{store ? store->getName() : "", 0},
+ mStore{store} {
+ }
+
+ virtual c2_status_t config(
+ const std::vector<C2Param*> ¶ms,
+ c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2SettingResult>> *const failures
+ ) override {
+ // Assume all params are blocking
+ // TODO: Filter for supported params
+ if (mayBlock == C2_DONT_BLOCK && params.size() != 0) {
+ return C2_BLOCKING;
+ }
+ return mStore->config_sm(params, failures);
+ }
+
+ virtual c2_status_t query(
+ const std::vector<C2Param::Index> &indices,
+ c2_blocking_t mayBlock,
+ std::vector<std::unique_ptr<C2Param>> *const params) const override {
+ // Assume all params are blocking
+ // TODO: Filter for supported params
+ if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) {
+ return C2_BLOCKING;
+ }
+ return mStore->query_sm({}, indices, params);
+ }
+
+ virtual c2_status_t querySupportedParams(
+ std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
+ ) const override {
+ return mStore->querySupportedParams_nb(params);
+ }
+
+ virtual c2_status_t querySupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields,
+ c2_blocking_t mayBlock) const override {
+ // Assume all params are blocking
+ // TODO: Filter for supported params
+ if (mayBlock == C2_DONT_BLOCK && fields.size() != 0) {
+ return C2_BLOCKING;
+ }
+ return mStore->querySupportedValues_sm(fields);
+ }
+
+protected:
+ std::shared_ptr<C2ComponentStore> mStore;
+};
+
+} // unnamed namespace
+
+struct ComponentStore::StoreParameterCache : public ParameterCache {
+ std::mutex mStoreMutex;
+ ComponentStore* mStore;
+
+ StoreParameterCache(ComponentStore* store): mStore{store} {
+ }
+
+ virtual c2_status_t validate(
+ const std::vector<std::shared_ptr<C2ParamDescriptor>>& params
+ ) override {
+ std::scoped_lock _lock(mStoreMutex);
+ return mStore ? mStore->validateSupportedParams(params) : C2_NO_INIT;
+ }
+
+ void onStoreDestroyed() {
+ std::scoped_lock _lock(mStoreMutex);
+ mStore = nullptr;
+ }
+};
+
+ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store)
+ : mConfigurable{new CachedConfigurable(std::make_unique<StoreIntf>(store))},
+ mParameterCache{std::make_shared<StoreParameterCache>(this)},
+ mStore{store} {
+
+ std::shared_ptr<C2ComponentStore> platformStore = android::GetCodec2PlatformComponentStore();
+ SetPreferredCodec2ComponentStore(store);
+
+ // Retrieve struct descriptors
+ mParamReflector = mStore->getParamReflector();
+
+ // Retrieve supported parameters from store
+ using namespace std::placeholders;
+ mInit = mConfigurable->init(mParameterCache);
+}
+
+ComponentStore::~ComponentStore() {
+ mParameterCache->onStoreDestroyed();
+}
+
+c2_status_t ComponentStore::status() const {
+ return mInit;
+}
+
+c2_status_t ComponentStore::validateSupportedParams(
+ const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) {
+ c2_status_t res = C2_OK;
+
+ for (const std::shared_ptr<C2ParamDescriptor> &desc : params) {
+ if (!desc) {
+ // All descriptors should be valid
+ res = res ? res : C2_BAD_VALUE;
+ continue;
+ }
+ C2Param::CoreIndex coreIndex = desc->index().coreIndex();
+ std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+ auto it = mStructDescriptors.find(coreIndex);
+ if (it == mStructDescriptors.end()) {
+ std::shared_ptr<C2StructDescriptor> structDesc =
+ mParamReflector->describe(coreIndex);
+ if (!structDesc) {
+ // All supported params must be described
+ res = C2_BAD_INDEX;
+ }
+ mStructDescriptors.insert({ coreIndex, structDesc });
+ }
+ }
+ return res;
+}
+
+std::shared_ptr<ParameterCache> ComponentStore::getParameterCache() const {
+ return mParameterCache;
+}
+
+// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
+Return<void> ComponentStore::createComponent(
+ const hidl_string& name,
+ const sp<IComponentListener>& listener,
+ const sp<IClientManager>& pool,
+ createComponent_cb _hidl_cb) {
+
+ sp<Component> component;
+ std::shared_ptr<C2Component> c2component;
+ Status status = static_cast<Status>(
+ mStore->createComponent(name, &c2component));
+
+ if (status == Status::OK) {
+ onInterfaceLoaded(c2component->intf());
+ component = new Component(c2component, listener, this, pool);
+ if (!component) {
+ status = Status::CORRUPTED;
+ } else {
+ reportComponentBirth(component.get());
+ if (component->status() != C2_OK) {
+ status = static_cast<Status>(component->status());
+ } else {
+ component->initListener(component);
+ if (component->status() != C2_OK) {
+ status = static_cast<Status>(component->status());
+ }
+ }
+ }
+ }
+ _hidl_cb(status, component);
+ return Void();
+}
+
+Return<void> ComponentStore::createInterface(
+ const hidl_string& name,
+ createInterface_cb _hidl_cb) {
+ std::shared_ptr<C2ComponentInterface> c2interface;
+ c2_status_t res = mStore->createInterface(name, &c2interface);
+ sp<IComponentInterface> interface;
+ if (res == C2_OK) {
+ onInterfaceLoaded(c2interface);
+ interface = new ComponentInterface(c2interface, mParameterCache);
+ }
+ _hidl_cb(static_cast<Status>(res), interface);
+ return Void();
+}
+
+Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) {
+ std::vector<std::shared_ptr<const C2Component::Traits>> c2traits =
+ mStore->listComponents();
+ hidl_vec<IComponentStore::ComponentTraits> traits(c2traits.size());
+ size_t ix = 0;
+ for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) {
+ if (c2trait) {
+ if (objcpy(&traits[ix], *c2trait)) {
+ ++ix;
+ } else {
+ break;
+ }
+ }
+ }
+ traits.resize(ix);
+ _hidl_cb(Status::OK, traits);
+ return Void();
+}
+
+Return<void> ComponentStore::createInputSurface(createInputSurface_cb _hidl_cb) {
+ sp<GraphicBufferSource> source = new GraphicBufferSource();
+ if (source->initCheck() != OK) {
+ _hidl_cb(Status::CORRUPTED, nullptr);
+ return Void();
+ }
+ using namespace std::placeholders;
+ sp<InputSurface> inputSurface = new InputSurface(
+ mParameterCache,
+ std::make_shared<C2ReflectorHelper>(),
+ source->getHGraphicBufferProducer(),
+ source);
+ _hidl_cb(inputSurface ? Status::OK : Status::NO_MEMORY,
+ inputSurface);
+ return Void();
+}
+
+void ComponentStore::onInterfaceLoaded(const std::shared_ptr<C2ComponentInterface> &intf) {
+ // invalidate unsupported struct descriptors if a new interface is loaded as it may have
+ // exposed new descriptors
+ std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+ if (!mLoadedInterfaces.count(intf->getName())) {
+ mUnsupportedStructDescriptors.clear();
+ mLoadedInterfaces.emplace(intf->getName());
+ }
+}
+
+Return<void> ComponentStore::getStructDescriptors(
+ const hidl_vec<uint32_t>& indices,
+ getStructDescriptors_cb _hidl_cb) {
+ hidl_vec<StructDescriptor> descriptors(indices.size());
+ size_t dstIx = 0;
+ Status res = Status::OK;
+ for (size_t srcIx = 0; srcIx < indices.size(); ++srcIx) {
+ std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
+ const C2Param::CoreIndex coreIndex = C2Param::CoreIndex(indices[srcIx]).coreIndex();
+ const auto item = mStructDescriptors.find(coreIndex);
+ if (item == mStructDescriptors.end()) {
+ // not in the cache, and not known to be unsupported, query local reflector
+ if (!mUnsupportedStructDescriptors.count(coreIndex)) {
+ std::shared_ptr<C2StructDescriptor> structDesc =
+ mParamReflector->describe(coreIndex);
+ if (!structDesc) {
+ mUnsupportedStructDescriptors.emplace(coreIndex);
+ } else {
+ mStructDescriptors.insert({ coreIndex, structDesc });
+ if (objcpy(&descriptors[dstIx], *structDesc)) {
+ ++dstIx;
+ continue;
+ }
+ res = Status::CORRUPTED;
+ break;
+ }
+ }
+ res = Status::NOT_FOUND;
+ } else if (item->second) {
+ if (objcpy(&descriptors[dstIx], *item->second)) {
+ ++dstIx;
+ continue;
+ }
+ res = Status::CORRUPTED;
+ break;
+ } else {
+ res = Status::NO_MEMORY;
+ break;
+ }
+ }
+ descriptors.resize(dstIx);
+ _hidl_cb(res, descriptors);
+ return Void();
+}
+
+Return<sp<IClientManager>> ComponentStore::getPoolClientManager() {
+ return ClientManager::getInstance();
+}
+
+Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst) {
+ // TODO implement
+ (void)src;
+ (void)dst;
+ return Status::OMITTED;
+}
+
+Return<sp<IConfigurable>> ComponentStore::getConfigurable() {
+ return mConfigurable;
+}
+
+// Methods from ::android::hardware::media::c2::V1_1::IComponentStore
+Return<void> ComponentStore::createComponent_1_1(
+ const hidl_string& name,
+ const sp<IComponentListener>& listener,
+ const sp<IClientManager>& pool,
+ createComponent_1_1_cb _hidl_cb) {
+
+ sp<Component> component;
+ std::shared_ptr<C2Component> c2component;
+ Status status = static_cast<Status>(
+ mStore->createComponent(name, &c2component));
+
+ if (status == Status::OK) {
+ onInterfaceLoaded(c2component->intf());
+ component = new Component(c2component, listener, this, pool);
+ if (!component) {
+ status = Status::CORRUPTED;
+ } else {
+ reportComponentBirth(component.get());
+ if (component->status() != C2_OK) {
+ status = static_cast<Status>(component->status());
+ } else {
+ component->initListener(component);
+ if (component->status() != C2_OK) {
+ status = static_cast<Status>(component->status());
+ }
+ }
+ }
+ }
+ _hidl_cb(status, component);
+ return Void();
+}
+
+// Called from createComponent() after a successful creation of `component`.
+void ComponentStore::reportComponentBirth(Component* component) {
+ ComponentStatus componentStatus;
+ componentStatus.c2Component = component->mComponent;
+ componentStatus.birthTime = std::chrono::system_clock::now();
+
+ std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+ mComponentRoster.emplace(component, componentStatus);
+}
+
+// Called from within the destructor of `component`. No virtual function calls
+// are made on `component` here.
+void ComponentStore::reportComponentDeath(Component* component) {
+ std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+ mComponentRoster.erase(component);
+}
+
+// Dumps component traits.
+std::ostream& ComponentStore::dump(
+ std::ostream& out,
+ const std::shared_ptr<const C2Component::Traits>& comp) {
+
+ constexpr const char indent[] = " ";
+
+ out << indent << "name: " << comp->name << std::endl;
+ out << indent << "domain: " << comp->domain << std::endl;
+ out << indent << "kind: " << comp->kind << std::endl;
+ out << indent << "rank: " << comp->rank << std::endl;
+ out << indent << "mediaType: " << comp->mediaType << std::endl;
+ out << indent << "aliases:";
+ for (const auto& alias : comp->aliases) {
+ out << ' ' << alias;
+ }
+ out << std::endl;
+
+ return out;
+}
+
+// Dumps component status.
+std::ostream& ComponentStore::dump(
+ std::ostream& out,
+ ComponentStatus& compStatus) {
+
+ constexpr const char indent[] = " ";
+
+ // Print birth time.
+ std::chrono::milliseconds ms =
+ std::chrono::duration_cast<std::chrono::milliseconds>(
+ compStatus.birthTime.time_since_epoch());
+ std::time_t birthTime = std::chrono::system_clock::to_time_t(
+ compStatus.birthTime);
+ std::tm tm = *std::localtime(&birthTime);
+ out << indent << "Creation time: "
+ << std::put_time(&tm, "%Y-%m-%d %H:%M:%S")
+ << '.' << std::setfill('0') << std::setw(3) << ms.count() % 1000
+ << std::endl;
+
+ // Print name and id.
+ std::shared_ptr<C2ComponentInterface> intf = compStatus.c2Component->intf();
+ if (!intf) {
+ out << indent << "Unknown component -- null interface" << std::endl;
+ return out;
+ }
+ out << indent << "Name: " << intf->getName() << std::endl;
+ out << indent << "Id: " << intf->getId() << std::endl;
+
+ return out;
+}
+
+// Dumps information when lshal is called.
+Return<void> ComponentStore::debug(
+ const hidl_handle& handle,
+ const hidl_vec<hidl_string>& /* args */) {
+ LOG(INFO) << "debug -- dumping...";
+ const native_handle_t *h = handle.getNativeHandle();
+ if (!h || h->numFds != 1) {
+ LOG(ERROR) << "debug -- dumping failed -- "
+ "invalid file descriptor to dump to";
+ return Void();
+ }
+ std::ostringstream out;
+
+ { // Populate "out".
+
+ constexpr const char indent[] = " ";
+
+ // Show name.
+ out << "Beginning of dump -- C2ComponentStore: "
+ << mStore->getName() << std::endl << std::endl;
+
+ // Retrieve the list of supported components.
+ std::vector<std::shared_ptr<const C2Component::Traits>> traitsList =
+ mStore->listComponents();
+
+ // Dump the traits of supported components.
+ out << indent << "Supported components:" << std::endl << std::endl;
+ if (traitsList.size() == 0) {
+ out << indent << indent << "NONE" << std::endl << std::endl;
+ } else {
+ for (const auto& traits : traitsList) {
+ dump(out, traits) << std::endl;
+ }
+ }
+
+ // Dump active components.
+ {
+ out << indent << "Active components:" << std::endl << std::endl;
+ std::lock_guard<std::mutex> lock(mComponentRosterMutex);
+ if (mComponentRoster.size() == 0) {
+ out << indent << indent << "NONE" << std::endl << std::endl;
+ } else {
+ for (auto& pair : mComponentRoster) {
+ dump(out, pair.second) << std::endl;
+ }
+ }
+ }
+
+ out << "End of dump -- C2ComponentStore: "
+ << mStore->getName() << std::endl;
+ }
+
+ if (!android::base::WriteStringToFd(out.str(), h->data[0])) {
+ PLOG(WARNING) << "debug -- dumping failed -- write()";
+ } else {
+ LOG(INFO) << "debug -- dumping succeeded";
+ }
+ return Void();
+}
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
diff --git a/media/codec2/hidl/1.1/utils/Configurable.cpp b/media/codec2/hidl/1.1/utils/Configurable.cpp
new file mode 100644
index 0000000..1f3b2c7
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/Configurable.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/Configurable.h>
diff --git a/media/codec2/hidl/1.1/utils/InputBufferManager.cpp b/media/codec2/hidl/1.1/utils/InputBufferManager.cpp
new file mode 100644
index 0000000..45bfc86
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/InputBufferManager.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/InputBufferManager.h>
diff --git a/media/codec2/hidl/1.1/utils/InputSurface.cpp b/media/codec2/hidl/1.1/utils/InputSurface.cpp
new file mode 100644
index 0000000..ce40494
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/InputSurface.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/InputSurface.h>
diff --git a/media/codec2/hidl/1.1/utils/InputSurfaceConnection.cpp b/media/codec2/hidl/1.1/utils/InputSurfaceConnection.cpp
new file mode 100644
index 0000000..32154a7
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/InputSurfaceConnection.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/InputSurfaceConnection.h>
diff --git a/media/codec2/hidl/1.1/utils/OutputBufferQueue.cpp b/media/codec2/hidl/1.1/utils/OutputBufferQueue.cpp
new file mode 100644
index 0000000..65756e8
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/OutputBufferQueue.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/OutputBufferQueue.h>
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h
new file mode 100644
index 0000000..16c81d4
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Component.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_COMPONENT_H
+#define CODEC2_HIDL_V1_1_UTILS_COMPONENT_H
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.1/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.1/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IInputSink.h>
+#include <codec2/hidl/1.1/ComponentInterface.h>
+#include <codec2/hidl/1.1/Configurable.h>
+#include <codec2/hidl/1.1/types.h>
+#include <hidl/Status.h>
+#include <hwbinder/IBinder.h>
+
+#include <C2Component.h>
+#include <C2Buffer.h>
+#include <C2.h>
+
+#include <map>
+#include <memory>
+#include <mutex>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+
+using ::android::hardware::media::c2::V1_1::IComponent;
+using ::android::hardware::media::c2::V1_0::IComponentListener;
+
+namespace utils {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::IBinder;
+using ::android::sp;
+using ::android::wp;
+
+struct ComponentStore;
+
+struct Component : public IComponent,
+ public std::enable_shared_from_this<Component> {
+ Component(
+ const std::shared_ptr<C2Component>&,
+ const sp<IComponentListener>& listener,
+ const sp<ComponentStore>& store,
+ const sp<::android::hardware::media::bufferpool::V2_0::
+ IClientManager>& clientPoolManager);
+ c2_status_t status() const;
+
+ typedef ::android::hardware::graphics::bufferqueue::V1_0::
+ IGraphicBufferProducer HGraphicBufferProducer1;
+ typedef ::android::hardware::graphics::bufferqueue::V2_0::
+ IGraphicBufferProducer HGraphicBufferProducer2;
+
+ // Methods from IComponent follow.
+ virtual Return<Status> queue(const WorkBundle& workBundle) override;
+ virtual Return<void> flush(flush_cb _hidl_cb) override;
+ virtual Return<Status> drain(bool withEos) override;
+ virtual Return<Status> setOutputSurface(
+ uint64_t blockPoolId,
+ const sp<HGraphicBufferProducer2>& surface) override;
+ virtual Return<void> connectToInputSurface(
+ const sp<IInputSurface>& inputSurface,
+ connectToInputSurface_cb _hidl_cb) override;
+ virtual Return<void> connectToOmxInputSurface(
+ const sp<HGraphicBufferProducer1>& producer,
+ const sp<::android::hardware::media::omx::V1_0::
+ IGraphicBufferSource>& source,
+ connectToOmxInputSurface_cb _hidl_cb) override;
+ virtual Return<Status> disconnectFromInputSurface() override;
+ virtual Return<void> createBlockPool(
+ uint32_t allocatorId,
+ createBlockPool_cb _hidl_cb) override;
+ virtual Return<Status> destroyBlockPool(uint64_t blockPoolId) override;
+ virtual Return<Status> start() override;
+ virtual Return<Status> stop() override;
+ virtual Return<Status> reset() override;
+ virtual Return<Status> release() override;
+ virtual Return<sp<IComponentInterface>> getInterface() override;
+ virtual Return<sp<IInputSink>> asInputSink() override;
+ virtual Return<void> configureVideoTunnel(
+ uint32_t avSyncHwId, configureVideoTunnel_cb _hidl_cb) override;
+
+ // Returns a C2Component associated to the given sink if the sink is indeed
+ // a local component. Returns nullptr otherwise.
+ //
+ // This function is used by InputSurface::connect().
+ static std::shared_ptr<C2Component> findLocalComponent(
+ const sp<IInputSink>& sink);
+
+protected:
+ c2_status_t mInit;
+ std::shared_ptr<C2Component> mComponent;
+ sp<ComponentInterface> mInterface;
+ sp<IComponentListener> mListener;
+ sp<ComponentStore> mStore;
+ ::android::hardware::media::c2::V1_1::utils::DefaultBufferPoolSender
+ mBufferPoolSender;
+
+ struct Sink;
+ std::mutex mSinkMutex;
+ sp<Sink> mSink;
+
+ std::mutex mBlockPoolsMutex;
+ // This map keeps C2BlockPool objects that are created by createBlockPool()
+ // alive. These C2BlockPool objects can be deleted by calling
+ // destroyBlockPool(), reset() or release(), or by destroying the component.
+ std::map<uint64_t, std::shared_ptr<C2BlockPool>> mBlockPools;
+
+ void initListener(const sp<Component>& self);
+
+ virtual ~Component() override;
+
+ friend struct ComponentStore;
+
+ struct Listener;
+};
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_COMPONENT_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentInterface.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentInterface.h
new file mode 100644
index 0000000..723c5bd
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentInterface.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_COMPONENT_INTERFACE_H
+#define CODEC2_HIDL_V1_1_UTILS_COMPONENT_INTERFACE_H
+
+#include <codec2/hidl/1.0/ComponentInterface.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::ComponentInterface;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_COMPONENT_INTERFACE_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
new file mode 100644
index 0000000..1f04391
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_COMPONENT_STORE_H
+#define CODEC2_HIDL_V1_1_UTILS_COMPONENT_STORE_H
+
+#include <codec2/hidl/1.1/Component.h>
+#include <codec2/hidl/1.1/ComponentInterface.h>
+#include <codec2/hidl/1.1/Configurable.h>
+#include <codec2/hidl/1.1/types.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.1/IComponentStore.h>
+#include <hidl/Status.h>
+
+#include <C2Component.h>
+#include <C2Param.h>
+#include <C2.h>
+
+#include <chrono>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::bufferpool::V2_0::IClientManager;
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ComponentStore : public IComponentStore {
+ ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
+ virtual ~ComponentStore();
+
+ /**
+ * Returns the status of the construction of this object.
+ */
+ c2_status_t status() const;
+
+ /**
+ * This function is called by CachedConfigurable::init() to validate
+ * supported parameters.
+ */
+ c2_status_t validateSupportedParams(
+ const std::vector<std::shared_ptr<C2ParamDescriptor>>& params);
+
+ /**
+ * Returns the store's ParameterCache. This is used for validation by
+ * Configurable::init().
+ */
+ std::shared_ptr<ParameterCache> getParameterCache() const;
+
+ // Methods from ::android::hardware::media::c2::V1_0::IComponentStore.
+ virtual Return<void> createComponent(
+ const hidl_string& name,
+ const sp<IComponentListener>& listener,
+ const sp<IClientManager>& pool,
+ createComponent_cb _hidl_cb) override;
+ virtual Return<void> createInterface(
+ const hidl_string& name,
+ createInterface_cb _hidl_cb) override;
+ virtual Return<void> listComponents(listComponents_cb _hidl_cb) override;
+ virtual Return<void> createInputSurface(
+ createInputSurface_cb _hidl_cb) override;
+ virtual Return<void> getStructDescriptors(
+ const hidl_vec<uint32_t>& indices,
+ getStructDescriptors_cb _hidl_cb) override;
+ virtual Return<sp<IClientManager>> getPoolClientManager() override;
+ virtual Return<Status> copyBuffer(
+ const Buffer& src,
+ const Buffer& dst) override;
+ virtual Return<sp<IConfigurable>> getConfigurable() override;
+
+ // Methods from ::android::hardware::media::c2::V1_1::IComponentStore.
+ virtual Return<void> createComponent_1_1(
+ const hidl_string& name,
+ const sp<IComponentListener>& listener,
+ const sp<IClientManager>& pool,
+ createComponent_1_1_cb _hidl_cb) override;
+
+ /**
+ * Dumps information when lshal is called.
+ */
+ virtual Return<void> debug(
+ const hidl_handle& handle,
+ const hidl_vec<hidl_string>& args) override;
+
+protected:
+ sp<CachedConfigurable> mConfigurable;
+ struct StoreParameterCache;
+ std::shared_ptr<StoreParameterCache> mParameterCache;
+
+ // Does bookkeeping for an interface that has been loaded.
+ void onInterfaceLoaded(const std::shared_ptr<C2ComponentInterface> &intf);
+
+ c2_status_t mInit;
+ std::shared_ptr<C2ComponentStore> mStore;
+ std::shared_ptr<C2ParamReflector> mParamReflector;
+
+ std::map<C2Param::CoreIndex, std::shared_ptr<C2StructDescriptor>> mStructDescriptors;
+ std::set<C2Param::CoreIndex> mUnsupportedStructDescriptors;
+ std::set<C2String> mLoadedInterfaces;
+ mutable std::mutex mStructDescriptorsMutex;
+
+ // ComponentStore keeps track of live Components.
+
+ struct ComponentStatus {
+ std::shared_ptr<C2Component> c2Component;
+ std::chrono::system_clock::time_point birthTime;
+ };
+
+ mutable std::mutex mComponentRosterMutex;
+ std::map<Component*, ComponentStatus> mComponentRoster;
+
+ // Called whenever Component is created.
+ void reportComponentBirth(Component* component);
+ // Called only from the destructor of Component.
+ void reportComponentDeath(Component* component);
+
+ friend Component;
+
+ // Helper functions for dumping.
+
+ std::ostream& dump(
+ std::ostream& out,
+ const std::shared_ptr<const C2Component::Traits>& comp);
+
+ std::ostream& dump(
+ std::ostream& out,
+ ComponentStatus& compStatus);
+
+};
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_COMPONENT_STORE_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Configurable.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Configurable.h
new file mode 100644
index 0000000..fd9091b
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/Configurable.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_CONFIGURABLE_H
+#define CODEC2_HIDL_V1_1_UTILS_CONFIGURABLE_H
+
+#include <codec2/hidl/1.0/Configurable.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::ConfigurableC2Intf;
+using ::android::hardware::media::c2::V1_0::utils::ParameterCache;
+using ::android::hardware::media::c2::V1_0::utils::CachedConfigurable;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_CONFIGURABLE_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputBufferManager.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputBufferManager.h
new file mode 100644
index 0000000..8e7a91b
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputBufferManager.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_INPUT_BUFFER_MANAGER_H
+#define CODEC2_HIDL_V1_1_UTILS_INPUT_BUFFER_MANAGER_H
+
+#include <codec2/hidl/1.0/InputBufferManager.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::InputBufferManager;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_INPUT_BUFFER_MANAGER_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurface.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurface.h
new file mode 100644
index 0000000..59223b7
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurface.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_H
+#define CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_H
+
+#include <codec2/hidl/1.0/InputSurface.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::InputSurface;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurfaceConnection.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurfaceConnection.h
new file mode 100644
index 0000000..7f695ef
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/InputSurfaceConnection.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_CONNECTION_H
+#define CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_CONNECTION_H
+
+#include <codec2/hidl/1.0/InputSurfaceConnection.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::InputSurfaceConnection;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_INPUT_SURFACE_CONNECTION_H
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/OutputBufferQueue.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/OutputBufferQueue.h
new file mode 100644
index 0000000..f77852d
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/OutputBufferQueue.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_OUTPUT_BUFFER_QUEUE
+#define CODEC2_HIDL_V1_1_UTILS_OUTPUT_BUFFER_QUEUE
+
+#include <codec2/hidl/1.0/OutputBufferQueue.h>
+#include <codec2/hidl/1.1/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_OUTPUT_BUFFER_QUEUE
diff --git a/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/types.h b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/types.h
new file mode 100644
index 0000000..d0ba93d
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/include/codec2/hidl/1.1/types.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC2_HIDL_V1_1_UTILS_TYPES_H
+#define CODEC2_HIDL_V1_1_UTILS_TYPES_H
+
+#include <android/hardware/media/c2/1.1/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.1/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <android/hardware/media/c2/1.0/IInputSink.h>
+#include <android/hardware/media/c2/1.0/IInputSurface.h>
+#include <android/hardware/media/c2/1.0/IInputSurfaceConnection.h>
+
+#include <codec2/hidl/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace media {
+namespace c2 {
+namespace V1_1 {
+
+using ::android::hardware::media::c2::V1_0::BaseBlock;
+using ::android::hardware::media::c2::V1_0::Block;
+using ::android::hardware::media::c2::V1_0::Buffer;
+using ::android::hardware::media::c2::V1_0::FieldDescriptor;
+using ::android::hardware::media::c2::V1_0::FieldId;
+using ::android::hardware::media::c2::V1_0::FieldSupportedValues;
+using ::android::hardware::media::c2::V1_0::FieldSupportedValuesQuery;
+using ::android::hardware::media::c2::V1_0::FieldSupportedValuesQueryResult;
+using ::android::hardware::media::c2::V1_0::FrameData;
+using ::android::hardware::media::c2::V1_0::InfoBuffer;
+using ::android::hardware::media::c2::V1_0::ParamDescriptor;
+using ::android::hardware::media::c2::V1_0::ParamField;
+using ::android::hardware::media::c2::V1_0::ParamFieldValues;
+using ::android::hardware::media::c2::V1_0::ParamIndex;
+using ::android::hardware::media::c2::V1_0::Params;
+using ::android::hardware::media::c2::V1_0::PrimitiveValue;
+using ::android::hardware::media::c2::V1_0::SettingResult;
+using ::android::hardware::media::c2::V1_0::Status;
+using ::android::hardware::media::c2::V1_0::StructDescriptor;
+using ::android::hardware::media::c2::V1_0::ValueRange;
+using ::android::hardware::media::c2::V1_0::Work;
+using ::android::hardware::media::c2::V1_0::WorkBundle;
+using ::android::hardware::media::c2::V1_0::WorkOrdinal;
+using ::android::hardware::media::c2::V1_0::Worklet;
+
+using ::android::hardware::media::c2::V1_0::IComponentInterface;
+using ::android::hardware::media::c2::V1_0::IComponentListener;
+using ::android::hardware::media::c2::V1_0::IConfigurable;
+using ::android::hardware::media::c2::V1_0::IInputSink;
+using ::android::hardware::media::c2::V1_0::IInputSurface;
+using ::android::hardware::media::c2::V1_0::IInputSurfaceConnection;
+
+namespace utils {
+
+using ::android::hardware::media::c2::V1_0::utils::toC2Status;
+
+using ::android::hardware::media::c2::V1_0::utils::C2Hidl_Range;
+using ::android::hardware::media::c2::V1_0::utils::C2Hidl_RangeInfo;
+using ::android::hardware::media::c2::V1_0::utils::C2Hidl_Rect;
+using ::android::hardware::media::c2::V1_0::utils::C2Hidl_RectInfo;
+
+using ::android::hardware::media::c2::V1_0::utils::objcpy;
+using ::android::hardware::media::c2::V1_0::utils::parseParamsBlob;
+using ::android::hardware::media::c2::V1_0::utils::createParamsBlob;
+using ::android::hardware::media::c2::V1_0::utils::copyParamsFromBlob;
+using ::android::hardware::media::c2::V1_0::utils::updateParamsFromBlob;
+
+using ::android::hardware::media::c2::V1_0::utils::BufferPoolSender;
+using ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender;
+
+using ::android::hardware::media::c2::V1_0::utils::beginTransferBufferQueueBlock;
+using ::android::hardware::media::c2::V1_0::utils::beginTransferBufferQueueBlocks;
+using ::android::hardware::media::c2::V1_0::utils::endTransferBufferQueueBlock;
+using ::android::hardware::media::c2::V1_0::utils::endTransferBufferQueueBlocks;
+using ::android::hardware::media::c2::V1_0::utils::displayBufferQueueBlock;
+
+using ::android::hardware::media::c2::V1_0::utils::operator<<;
+
+} // namespace utils
+} // namespace V1_1
+} // namespace c2
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // CODEC2_HIDL_V1_1_UTILS_TYPES_H
diff --git a/media/codec2/hidl/1.1/utils/types.cpp b/media/codec2/hidl/1.1/utils/types.cpp
new file mode 100644
index 0000000..8c09023
--- /dev/null
+++ b/media/codec2/hidl/1.1/utils/types.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <codec2/hidl/1.1/types.h>
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
index 89c1c4a..3c37990 100644
--- a/media/codec2/hidl/client/Android.bp
+++ b/media/codec2/hidl/client/Android.bp
@@ -9,10 +9,12 @@
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.media.bufferpool@2.0",
"android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
"libbase",
"libbinder",
"libcodec2",
"libcodec2_hidl_client@1.0",
+ "libcodec2_hidl_client@1.1",
"libcodec2_vndk",
"libcutils",
"libgui",
@@ -28,8 +30,11 @@
],
export_shared_lib_headers: [
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
"libcodec2",
"libcodec2_hidl_client@1.0",
+ "libcodec2_hidl_client@1.1",
"libcodec2_vndk",
],
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index c747190..199a99c 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -19,6 +19,29 @@
#include <android-base/logging.h>
#include <codec2/hidl/client.h>
+#include <C2Debug.h>
+#include <C2BufferPriv.h>
+#include <C2PlatformSupport.h>
+
+#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
+#include <android/hardware/media/c2/1.0/IComponent.h>
+#include <android/hardware/media/c2/1.0/IComponentInterface.h>
+#include <android/hardware/media/c2/1.0/IComponentListener.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
+#include <android/hardware/media/c2/1.0/IConfigurable.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+#include <android-base/properties.h>
+#include <bufferpool/ClientManager.h>
+#include <codec2/hidl/1.0/OutputBufferQueue.h>
+#include <codec2/hidl/1.0/types.h>
+#include <codec2/hidl/1.1/OutputBufferQueue.h>
+#include <codec2/hidl/1.1/types.h>
+
+#include <cutils/native_handle.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+#include <hidl/HidlSupport.h>
#include <deque>
#include <iterator>
@@ -30,25 +53,6 @@
#include <type_traits>
#include <vector>
-#include <android-base/properties.h>
-#include <bufferpool/ClientManager.h>
-#include <cutils/native_handle.h>
-#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
-#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
-#include <hidl/HidlSupport.h>
-
-#include <android/hardware/media/bufferpool/2.0/IClientManager.h>
-#include <android/hardware/media/c2/1.0/IComponent.h>
-#include <android/hardware/media/c2/1.0/IComponentInterface.h>
-#include <android/hardware/media/c2/1.0/IComponentListener.h>
-#include <android/hardware/media/c2/1.0/IComponentStore.h>
-#include <android/hardware/media/c2/1.0/IConfigurable.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-
-#include <C2Debug.h>
-#include <C2BufferPriv.h>
-#include <C2PlatformSupport.h>
-
namespace android {
using ::android::hardware::hidl_vec;
@@ -56,8 +60,8 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
-using namespace ::android::hardware::media::c2::V1_0;
-using namespace ::android::hardware::media::c2::V1_0::utils;
+using namespace ::android::hardware::media::c2::V1_1;
+using namespace ::android::hardware::media::c2::V1_1::utils;
using namespace ::android::hardware::media::bufferpool::V2_0;
using namespace ::android::hardware::media::bufferpool::V2_0::implementation;
@@ -514,8 +518,24 @@
};
+// Codec2Client::Component::BufferPoolSender
+struct Codec2Client::Component::BufferPoolSender :
+ hardware::media::c2::V1_1::utils::DefaultBufferPoolSender {
+ BufferPoolSender()
+ : hardware::media::c2::V1_1::utils::DefaultBufferPoolSender() {
+ }
+};
+
+// Codec2Client::Component::OutputBufferQueue
+struct Codec2Client::Component::OutputBufferQueue :
+ hardware::media::c2::V1_1::utils::OutputBufferQueue {
+ OutputBufferQueue()
+ : hardware::media::c2::V1_1::utils::OutputBufferQueue() {
+ }
+};
+
// Codec2Client
-Codec2Client::Codec2Client(const sp<IComponentStore>& base,
+Codec2Client::Codec2Client(sp<Base> const& base,
size_t serviceIndex)
: Configurable{
[base]() -> sp<IConfigurable> {
@@ -526,7 +546,8 @@
nullptr;
}()
},
- mBase{base},
+ mBase1_0{base},
+ mBase1_1{Base1_1::castFrom(base)},
mServiceIndex{serviceIndex} {
Return<sp<IClientManager>> transResult = base->getPoolClientManager();
if (!transResult.isOk()) {
@@ -537,7 +558,15 @@
}
sp<Codec2Client::Base> const& Codec2Client::getBase() const {
- return mBase;
+ return mBase1_0;
+}
+
+sp<Codec2Client::Base1_0> const& Codec2Client::getBase1_0() const {
+ return mBase1_0;
+}
+
+sp<Codec2Client::Base1_1> const& Codec2Client::getBase1_1() const {
+ return mBase1_1;
}
std::string const& Codec2Client::getServiceName() const {
@@ -552,7 +581,8 @@
c2_status_t status;
sp<Component::HidlListener> hidlListener = new Component::HidlListener{};
hidlListener->base = listener;
- Return<void> transStatus = mBase->createComponent(
+ Return<void> transStatus = mBase1_1 ?
+ mBase1_1->createComponent_1_1(
name,
hidlListener,
ClientManager::getInstance(),
@@ -565,6 +595,20 @@
}
*component = std::make_shared<Codec2Client::Component>(c);
hidlListener->component = *component;
+ }) :
+ mBase1_0->createComponent(
+ name,
+ hidlListener,
+ ClientManager::getInstance(),
+ [&status, component, hidlListener](
+ Status s,
+ const sp<hardware::media::c2::V1_0::IComponent>& c) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK) {
+ return;
+ }
+ *component = std::make_shared<Codec2Client::Component>(c);
+ hidlListener->component = *component;
});
if (!transStatus.isOk()) {
LOG(ERROR) << "createComponent(" << name.c_str()
@@ -587,7 +631,7 @@
<< status << ".";
}
- (*component)->mBufferPoolSender.setReceiver(mHostPoolManager);
+ (*component)->mBufferPoolSender->setReceiver(mHostPoolManager);
return status;
}
@@ -595,7 +639,7 @@
const C2String& name,
std::shared_ptr<Codec2Client::Interface>* const interface) {
c2_status_t status;
- Return<void> transStatus = mBase->createInterface(
+ Return<void> transStatus = mBase1_0->createInterface(
name,
[&status, interface](
Status s,
@@ -622,7 +666,7 @@
c2_status_t Codec2Client::createInputSurface(
std::shared_ptr<InputSurface>* const inputSurface) {
c2_status_t status;
- Return<void> transStatus = mBase->createInputSurface(
+ Return<void> transStatus = mBase1_0->createInputSurface(
[&status, inputSurface](
Status s,
const sp<IInputSurface>& i) {
@@ -650,7 +694,7 @@
bool* success) const {
std::vector<C2Component::Traits> traits;
std::string const& serviceName = getServiceName();
- Return<void> transStatus = mBase->listComponents(
+ Return<void> transStatus = mBase1_0->listComponents(
[&traits, &serviceName](Status s,
const hidl_vec<IComponentStore::ComponentTraits>& t) {
if (s != Status::OK) {
@@ -734,7 +778,7 @@
sp<Base> mBase;
};
- return std::make_shared<SimpleParamReflector>(mBase);
+ return std::make_shared<SimpleParamReflector>(mBase1_0);
};
std::vector<std::string> const& Codec2Client::GetServiceNames() {
@@ -1053,8 +1097,32 @@
nullptr;
}()
},
- mBase{base},
- mBufferPoolSender{nullptr} {
+ mBase1_0{base},
+ mBase1_1{Base1_1::castFrom(base)},
+ mBufferPoolSender{std::make_unique<BufferPoolSender>()},
+ mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
+}
+
+Codec2Client::Component::Component(const sp<Base1_1>& base)
+ : Configurable{
+ [base]() -> sp<IConfigurable> {
+ Return<sp<IComponentInterface>> transResult1 =
+ base->getInterface();
+ if (!transResult1.isOk()) {
+ return nullptr;
+ }
+ Return<sp<IConfigurable>> transResult2 =
+ static_cast<sp<IComponentInterface>>(transResult1)->
+ getConfigurable();
+ return transResult2.isOk() ?
+ static_cast<sp<IConfigurable>>(transResult2) :
+ nullptr;
+ }()
+ },
+ mBase1_0{base},
+ mBase1_1{base},
+ mBufferPoolSender{std::make_unique<BufferPoolSender>()},
+ mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
}
Codec2Client::Component::~Component() {
@@ -1065,7 +1133,7 @@
C2BlockPool::local_id_t* blockPoolId,
std::shared_ptr<Codec2Client::Configurable>* configurable) {
c2_status_t status;
- Return<void> transStatus = mBase->createBlockPool(
+ Return<void> transStatus = mBase1_0->createBlockPool(
static_cast<uint32_t>(id),
[&status, blockPoolId, configurable](
Status s,
@@ -1090,7 +1158,7 @@
c2_status_t Codec2Client::Component::destroyBlockPool(
C2BlockPool::local_id_t localId) {
- Return<Status> transResult = mBase->destroyBlockPool(
+ Return<Status> transResult = mBase1_0->destroyBlockPool(
static_cast<uint64_t>(localId));
if (!transResult.isOk()) {
LOG(ERROR) << "destroyBlockPool -- transaction failed.";
@@ -1102,17 +1170,17 @@
void Codec2Client::Component::handleOnWorkDone(
const std::list<std::unique_ptr<C2Work>> &workItems) {
// Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue.holdBufferQueueBlocks(workItems);
+ mOutputBufferQueue->holdBufferQueueBlocks(workItems);
}
c2_status_t Codec2Client::Component::queue(
std::list<std::unique_ptr<C2Work>>* const items) {
WorkBundle workBundle;
- if (!objcpy(&workBundle, *items, &mBufferPoolSender)) {
+ if (!objcpy(&workBundle, *items, mBufferPoolSender.get())) {
LOG(ERROR) << "queue -- bad input.";
return C2_TRANSACTION_FAILED;
}
- Return<Status> transStatus = mBase->queue(workBundle);
+ Return<Status> transStatus = mBase1_0->queue(workBundle);
if (!transStatus.isOk()) {
LOG(ERROR) << "queue -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1130,7 +1198,7 @@
std::list<std::unique_ptr<C2Work>>* const flushedWork) {
(void)mode; // Flush mode isn't supported in HIDL yet.
c2_status_t status;
- Return<void> transStatus = mBase->flush(
+ Return<void> transStatus = mBase1_0->flush(
[&status, flushedWork](
Status s, const WorkBundle& wb) {
status = static_cast<c2_status_t>(s);
@@ -1165,13 +1233,13 @@
}
// Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue.holdBufferQueueBlocks(*flushedWork);
+ mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
return status;
}
c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
- Return<Status> transStatus = mBase->drain(
+ Return<Status> transStatus = mBase1_0->drain(
mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
if (!transStatus.isOk()) {
LOG(ERROR) << "drain -- transaction failed.";
@@ -1186,7 +1254,7 @@
}
c2_status_t Codec2Client::Component::start() {
- Return<Status> transStatus = mBase->start();
+ Return<Status> transStatus = mBase1_0->start();
if (!transStatus.isOk()) {
LOG(ERROR) << "start -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1200,7 +1268,7 @@
}
c2_status_t Codec2Client::Component::stop() {
- Return<Status> transStatus = mBase->stop();
+ Return<Status> transStatus = mBase1_0->stop();
if (!transStatus.isOk()) {
LOG(ERROR) << "stop -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1214,7 +1282,7 @@
}
c2_status_t Codec2Client::Component::reset() {
- Return<Status> transStatus = mBase->reset();
+ Return<Status> transStatus = mBase1_0->reset();
if (!transStatus.isOk()) {
LOG(ERROR) << "reset -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1228,7 +1296,7 @@
}
c2_status_t Codec2Client::Component::release() {
- Return<Status> transStatus = mBase->release();
+ Return<Status> transStatus = mBase1_0->release();
if (!transStatus.isOk()) {
LOG(ERROR) << "release -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1241,6 +1309,29 @@
return status;
}
+c2_status_t Codec2Client::Component::configureVideoTunnel(
+ uint32_t avSyncHwId,
+ native_handle_t** sidebandHandle) {
+ *sidebandHandle = nullptr;
+ if (!mBase1_1) {
+ return C2_OMITTED;
+ }
+ c2_status_t status{};
+ Return<void> transStatus = mBase1_1->configureVideoTunnel(avSyncHwId,
+ [&status, sidebandHandle](
+ Status s, hardware::hidl_handle const& h) {
+ status = static_cast<c2_status_t>(s);
+ if (h.getNativeHandle()) {
+ *sidebandHandle = native_handle_clone(h.getNativeHandle());
+ }
+ });
+ if (!transStatus.isOk()) {
+ LOG(ERROR) << "configureVideoTunnel -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+}
+
c2_status_t Codec2Client::Component::setOutputSurface(
C2BlockPool::local_id_t blockPoolId,
const sp<IGraphicBufferProducer>& surface,
@@ -1256,18 +1347,18 @@
}
if (!surface) {
- mOutputBufferQueue.configure(nullIgbp, generation, 0);
+ mOutputBufferQueue->configure(nullIgbp, generation, 0);
} else if (surface->getUniqueId(&bqId) != OK) {
LOG(ERROR) << "setOutputSurface -- "
"cannot obtain bufferqueue id.";
bqId = 0;
- mOutputBufferQueue.configure(nullIgbp, generation, 0);
+ mOutputBufferQueue->configure(nullIgbp, generation, 0);
} else {
- mOutputBufferQueue.configure(surface, generation, bqId);
+ mOutputBufferQueue->configure(surface, generation, bqId);
}
ALOGD("generation remote change %u", generation);
- Return<Status> transStatus = mBase->setOutputSurface(
+ Return<Status> transStatus = mBase1_0->setOutputSurface(
static_cast<uint64_t>(blockPoolId),
bqId == 0 ? nullHgbp : igbp);
if (!transStatus.isOk()) {
@@ -1286,14 +1377,14 @@
const C2ConstGraphicBlock& block,
const QueueBufferInput& input,
QueueBufferOutput* output) {
- return mOutputBufferQueue.outputBuffer(block, input, output);
+ return mOutputBufferQueue->outputBuffer(block, input, output);
}
c2_status_t Codec2Client::Component::connectToInputSurface(
const std::shared_ptr<InputSurface>& inputSurface,
std::shared_ptr<InputSurfaceConnection>* connection) {
c2_status_t status;
- Return<void> transStatus = mBase->connectToInputSurface(
+ Return<void> transStatus = mBase1_0->connectToInputSurface(
inputSurface->mBase,
[&status, connection](
Status s, const sp<IInputSurfaceConnection>& c) {
@@ -1317,7 +1408,7 @@
const sp<HGraphicBufferSource>& source,
std::shared_ptr<InputSurfaceConnection>* connection) {
c2_status_t status;
- Return<void> transStatus = mBase->connectToOmxInputSurface(
+ Return<void> transStatus = mBase1_0->connectToOmxInputSurface(
producer, source,
[&status, connection](
Status s, const sp<IInputSurfaceConnection>& c) {
@@ -1337,7 +1428,7 @@
}
c2_status_t Codec2Client::Component::disconnectFromInputSurface() {
- Return<Status> transStatus = mBase->disconnectFromInputSurface();
+ Return<Status> transStatus = mBase1_0->disconnectFromInputSurface();
if (!transStatus.isOk()) {
LOG(ERROR) << "disconnectToInputSurface -- transaction failed.";
return C2_TRANSACTION_FAILED;
@@ -1376,7 +1467,7 @@
deathRecipient->component = component;
component->mDeathRecipient = deathRecipient;
- Return<bool> transResult = component->mBase->linkToDeath(
+ Return<bool> transResult = component->mBase1_0->linkToDeath(
component->mDeathRecipient, 0);
if (!transResult.isOk()) {
LOG(ERROR) << "setDeathListener -- linkToDeath() transaction failed.";
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index dca28f7..649dffd 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -17,14 +17,13 @@
#ifndef CODEC2_HIDL_CLIENT_H
#define CODEC2_HIDL_CLIENT_H
-#include <gui/IGraphicBufferProducer.h>
-#include <codec2/hidl/1.0/OutputBufferQueue.h>
#include <C2PlatformSupport.h>
#include <C2Component.h>
#include <C2Buffer.h>
#include <C2Param.h>
#include <C2.h>
+#include <gui/IGraphicBufferProducer.h>
#include <hidl/HidlSupport.h>
#include <utils/StrongPointer.h>
@@ -74,6 +73,11 @@
struct IInputSurfaceConnection;
} // namespace android::hardware::media::c2::V1_0
+namespace android::hardware::media::c2::V1_1 {
+struct IComponent;
+struct IComponentStore;
+} // namespace android::hardware::media::c2::V1_1
+
namespace android::hardware::media::bufferpool::V2_0 {
struct IClientManager;
} // namespace android::hardware::media::bufferpool::V2_0
@@ -82,6 +86,10 @@
struct IGraphicBufferProducer;
} // android::hardware::graphics::bufferqueue::V1_0
+namespace android::hardware::graphics::bufferqueue::V2_0 {
+struct IGraphicBufferProducer;
+} // android::hardware::graphics::bufferqueue::V2_0
+
namespace android::hardware::media::omx::V1_0 {
struct IGraphicBufferSource;
} // namespace android::hardware::media::omx::V1_0
@@ -127,7 +135,9 @@
struct Codec2Client : public Codec2ConfigurableClient {
- typedef ::android::hardware::media::c2::V1_0::IComponentStore Base;
+ typedef ::android::hardware::media::c2::V1_0::IComponentStore Base1_0;
+ typedef ::android::hardware::media::c2::V1_1::IComponentStore Base1_1;
+ typedef Base1_0 Base;
struct Listener;
@@ -144,6 +154,8 @@
typedef Codec2Client Store;
sp<Base> const& getBase() const;
+ sp<Base1_0> const& getBase1_0() const;
+ sp<Base1_1> const& getBase1_1() const;
std::string const& getServiceName() const;
@@ -206,7 +218,8 @@
Codec2Client(sp<Base> const& base, size_t serviceIndex);
protected:
- sp<Base> mBase;
+ sp<Base1_0> mBase1_0;
+ sp<Base1_1> mBase1_1;
// Finds the first store where the predicate returns C2_OK and returns the
// last predicate result. The predicate will be tried on all stores. The
@@ -295,7 +308,9 @@
struct Codec2Client::Component : public Codec2Client::Configurable {
- typedef ::android::hardware::media::c2::V1_0::IComponent Base;
+ typedef ::android::hardware::media::c2::V1_0::IComponent Base1_0;
+ typedef ::android::hardware::media::c2::V1_1::IComponent Base1_1;
+ typedef Base1_0 Base;
c2_status_t createBlockPool(
C2Allocator::id_t id,
@@ -322,6 +337,17 @@
c2_status_t release();
+ /**
+ * Use tunneling.
+ *
+ * On success, @p sidebandHandle will be a newly allocated native handle.
+ * File descriptors in @p sidebandHandle must be closed and
+ * @p sidebandHandle itself must be deleted afterwards.
+ */
+ c2_status_t configureVideoTunnel(
+ uint32_t avSyncHwId,
+ native_handle_t** sidebandHandle);
+
typedef ::android::
IGraphicBufferProducer IGraphicBufferProducer;
typedef IGraphicBufferProducer::
@@ -378,17 +404,19 @@
// base cannot be null.
Component(const sp<Base>& base);
+ Component(const sp<Base1_1>& base);
~Component();
protected:
- sp<Base> mBase;
+ sp<Base1_0> mBase1_0;
+ sp<Base1_1> mBase1_1;
- ::android::hardware::media::c2::V1_0::utils::DefaultBufferPoolSender
- mBufferPoolSender;
+ struct BufferPoolSender;
+ std::unique_ptr<BufferPoolSender> mBufferPoolSender;
- ::android::hardware::media::c2::V1_0::utils::OutputBufferQueue
- mOutputBufferQueue;
+ struct OutputBufferQueue;
+ std::unique_ptr<OutputBufferQueue> mOutputBufferQueue;
static c2_status_t setDeathListener(
const std::shared_ptr<Component>& component,
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index 0403a1f..46bea2e 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -1,37 +1,82 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This is an example of an empty Codec2.0 service.
+//
+// To use this, make a copy of this whole directory and rename modules
+// accordingly. The contents of "vendor.cpp" and files in the subdirectory
+// "seccomp_policy" may also need to be modified.
+
+// Binary file for the service.
+//
+// The init_rc file contains the absolute path to this binary on the device.
+// If the name of this module is modified, the content of the init_rc file has
+// to be modified accordingly.
+//
+// The seccomp_policy file name and its content can be modified, but note that
+// vendor.cpp also needs to be updated because it needs the absolute path to the
+// seccomp policy file on the device.
cc_binary {
- name: "android.hardware.media.c2@1.0-service",
- defaults: ["hidl_defaults"],
- soc_specific: true,
+ name: "android.hardware.media.c2@1.1-default-service",
+ vendor: true,
relative_install_path: "hw",
+
+ init_rc: ["android.hardware.media.c2@1.1-default-service.rc"],
+
+ defaults: ["libcodec2-hidl-defaults"],
srcs: [
"vendor.cpp",
],
- init_rc: ["android.hardware.media.c2@1.0-service.rc"],
-
+ // minijail is used to protect against unexpected system calls.
shared_libs: [
- "android.hardware.media.c2@1.0",
- "android.hardware.media.omx@1.0",
"libavservices_minijail_vendor",
"libbinder",
- "libcodec2_hidl@1.0",
- "libcodec2_vndk",
- "libhidlbase",
- "liblog",
- "libstagefright_omx",
- "libstagefright_xmlparser",
- "libutils",
],
+ required: ["android.hardware.media.c2@1.1-default-seccomp_policy"],
+}
+// seccomp policy file.
+//
+// This should be modified to suit the target device and architecture.
+//
+// Files in the "seccomp_policy" subdirectory are only provided as examples.
+// They may not work on some devices and/or architectures without modification.
+prebuilt_etc {
+ name: "android.hardware.media.c2@1.1-default-seccomp_policy",
+ vendor: true,
+ sub_dir: "seccomp_policy",
+
+ // If a specific architecture is targeted, multiple choices are not needed.
arch: {
arm: {
- required: ["codec2.vendor.base.policy"],
+ src: "seccomp_policy/android.hardware.media.c2@1.1-default-arm.policy",
+ },
+ arm64: {
+ src: "seccomp_policy/android.hardware.media.c2@1.1-default-arm64.policy",
},
x86: {
- required: ["codec2.vendor.base.policy"],
+ src: "seccomp_policy/android.hardware.media.c2@1.1-default-x86.policy",
+ },
+ x86_64: {
+ src: "seccomp_policy/android.hardware.media.c2@1.1-default-x86_64.policy",
},
},
- compile_multilib: "32",
+ // This may be removed.
+ required: ["crash_dump.policy"],
}
diff --git a/media/codec2/hidl/services/Android.mk b/media/codec2/hidl/services/Android.mk
deleted file mode 100644
index d9b28e7..0000000
--- a/media/codec2/hidl/services/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# vendor service seccomp policy
-ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := codec2.vendor.base.policy
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-ifdef TARGET_2ND_ARCH
- ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_2ND_ARCH).policy
- else
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
- endif
-else
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
-endif
-include $(BUILD_PREBUILT)
-endif
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
-
diff --git a/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc b/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc
deleted file mode 100644
index 8806bd1f..0000000
--- a/media/codec2/hidl/services/android.hardware.media.c2@1.0-service.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service android-hardware-media-c2-hal-1-0 /vendor/bin/hw/android.hardware.media.c2@1.0-service
- class hal
- user mediacodec
- group camera mediadrm drmrpc
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
-
diff --git a/media/codec2/hidl/services/android.hardware.media.c2@1.1-default-service.rc b/media/codec2/hidl/services/android.hardware.media.c2@1.1-default-service.rc
new file mode 100644
index 0000000..44f2d8e
--- /dev/null
+++ b/media/codec2/hidl/services/android.hardware.media.c2@1.1-default-service.rc
@@ -0,0 +1,7 @@
+service android-hardware-media-c2-hal-1-1 /vendor/bin/hw/android.hardware.media.c2@1.1-default-service
+ class hal
+ user mediacodec
+ group camera mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
+
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm.policy
similarity index 70%
copy from media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
copy to media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm.policy
index d5871d1..9042cd7 100644
--- a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
+++ b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm.policy
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,21 +12,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Organized by frequency of systemcall - in descending order for
-# best performance.
futex: 1
+# ioctl calls are filtered via the selinux policy.
ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
+sched_yield: 1
close: 1
-writev: 1
dup: 1
ppoll: 1
-mmap2: 1
-getrandom: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap2: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
# parser support for '<' is in this needs to be modified to also prevent
@@ -36,38 +33,54 @@
# for more details.
mremap: arg3 == 3
munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
+prctl: 1
+getuid32: 1
+writev: 1
sigaltstack: 1
clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
lseek: 1
+rt_sigprocmask: 1
+openat: 1
+open: 1
+fstat64: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
+getdents64: 1
+readlinkat: 1
+readlink: 1
+read: 1
+pread64: 1
+fstatfs64: 1
+gettimeofday: 1
+faccessat: 1
_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
fstatat64: 1
ugetrlimit: 1
-getdents64: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
getrandom: 1
+madvise: 1
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
+# crash dump policy additions
+sigreturn: 1
+clock_gettime: 1
+futex: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#prctl: arg0 == PR_GET_NO_NEW_PRIVS || arg0 == 0x53564d41
+#mprotect: arg2 in 0x1|0x2
+#mmap2: arg2 in 0x1|0x2
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm64.policy
similarity index 71%
rename from media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
rename to media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm64.policy
index d5871d1..4faf8b2 100644
--- a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-arm.policy
+++ b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-arm64.policy
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,21 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Organized by frequency of systemcall - in descending order for
-# best performance.
futex: 1
+# ioctl calls are filtered via the selinux policy.
ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
+sched_yield: 1
close: 1
-writev: 1
dup: 1
ppoll: 1
-mmap2: 1
-getrandom: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+getuid: 1
+getrlimit: 1
+fstat: 1
+newfstatat: 1
+fstatfs: 1
+memfd_create: 1
+ftruncate: 1
# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
# parser support for '<' is in this needs to be modified to also prevent
@@ -36,38 +37,45 @@
# for more details.
mremap: arg3 == 3
munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
+prctl: 1
+writev: 1
sigaltstack: 1
clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
+rt_sigprocmask: 1
+openat: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
getdents64: 1
+readlinkat: 1
+read: 1
+pread64: 1
+gettimeofday: 1
+faccessat: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
getrandom: 1
+madvise: 1
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
+# crash dump policy additions
+clock_gettime: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#mprotect: arg2 in 0x1|0x2
+munmap: 1
+#mmap: arg2 in 0x1|0x2
+geteuid: 1
+getgid: 1
+getegid: 1
+getgroups: 1
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86.policy
similarity index 81%
rename from media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
rename to media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86.policy
index 20c7625..d9c4045 100644
--- a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
+++ b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86.policy
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,14 +16,22 @@
mprotect: 1
prctl: 1
openat: 1
+open: 1
getuid32: 1
+getuid: 1
+getrlimit: 1
writev: 1
ioctl: 1
close: 1
mmap2: 1
+mmap: 1
fstat64: 1
+fstat: 1
+stat64: 1
+statfs64: 1
madvise: 1
fstatat64: 1
+newfstatat: 1
futex: 1
munmap: 1
faccessat: 1
@@ -37,15 +45,22 @@
exit_group: 1
rt_sigreturn: 1
ugetrlimit: 1
+readlink: 1
readlinkat: 1
_llseek: 1
fstatfs64: 1
+fstatfs: 1
pread64: 1
mremap: 1
dup: 1
set_tid_address: 1
write: 1
nanosleep: 1
+sched_setscheduler: 1
+uname: 1
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
# Required by AddressSanitizer
gettid: 1
@@ -54,4 +69,3 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86_64.policy
similarity index 81%
copy from media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
copy to media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86_64.policy
index 20c7625..d9c4045 100644
--- a/media/codec2/hidl/services/seccomp_policy/codec2.software.base-x86.policy
+++ b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.1-default-x86_64.policy
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,14 +16,22 @@
mprotect: 1
prctl: 1
openat: 1
+open: 1
getuid32: 1
+getuid: 1
+getrlimit: 1
writev: 1
ioctl: 1
close: 1
mmap2: 1
+mmap: 1
fstat64: 1
+fstat: 1
+stat64: 1
+statfs64: 1
madvise: 1
fstatat64: 1
+newfstatat: 1
futex: 1
munmap: 1
faccessat: 1
@@ -37,15 +45,22 @@
exit_group: 1
rt_sigreturn: 1
ugetrlimit: 1
+readlink: 1
readlinkat: 1
_llseek: 1
fstatfs64: 1
+fstatfs: 1
pread64: 1
mremap: 1
dup: 1
set_tid_address: 1
write: 1
nanosleep: 1
+sched_setscheduler: 1
+uname: 1
+memfd_create: 1
+ftruncate: 1
+ftruncate64: 1
# Required by AddressSanitizer
gettid: 1
@@ -54,4 +69,3 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy
deleted file mode 100644
index d5871d1..0000000
--- a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-arm.policy
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Organized by frequency of systemcall - in descending order for
-# best performance.
-futex: 1
-ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
-close: 1
-writev: 1
-dup: 1
-ppoll: 1
-mmap2: 1
-getrandom: 1
-
-# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
-# parser support for '<' is in this needs to be modified to also prevent
-# |old_address| and |new_address| from touching the exception vector page, which
-# on ARM is statically loaded at 0xffff 0000. See
-# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
-# for more details.
-mremap: arg3 == 3
-munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
-sigaltstack: 1
-clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
-exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
-lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
-getdents64: 1
-getrandom: 1
-
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
diff --git a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy b/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy
deleted file mode 100644
index 20c7625..0000000
--- a/media/codec2/hidl/services/seccomp_policy/codec2.vendor.base-x86.policy
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-read: 1
-mprotect: 1
-prctl: 1
-openat: 1
-getuid32: 1
-writev: 1
-ioctl: 1
-close: 1
-mmap2: 1
-fstat64: 1
-madvise: 1
-fstatat64: 1
-futex: 1
-munmap: 1
-faccessat: 1
-_llseek: 1
-lseek: 1
-clone: 1
-sigaltstack: 1
-setpriority: 1
-restart_syscall: 1
-exit: 1
-exit_group: 1
-rt_sigreturn: 1
-ugetrlimit: 1
-readlinkat: 1
-_llseek: 1
-fstatfs64: 1
-pread64: 1
-mremap: 1
-dup: 1
-set_tid_address: 1
-write: 1
-nanosleep: 1
-
-# Required by AddressSanitizer
-gettid: 1
-sched_yield: 1
-getpid: 1
-gettid: 1
-
-@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/media/codec2/hidl/services/vendor.cpp b/media/codec2/hidl/services/vendor.cpp
index ef2f98e..65bb6f7 100644
--- a/media/codec2/hidl/services/vendor.cpp
+++ b/media/codec2/hidl/services/vendor.cpp
@@ -15,25 +15,27 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "android.hardware.media.c2@1.0-service"
+#define LOG_TAG "android.hardware.media.c2@1.1-service"
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <hidl/HidlTransportSupport.h>
+#include <android-base/logging.h>
#include <binder/ProcessState.h>
+#include <codec2/hidl/1.1/ComponentStore.h>
+#include <hidl/HidlTransportSupport.h>
#include <minijail.h>
#include <C2Component.h>
-// OmxStore is added for visibility by dumpstate.
-#include <media/stagefright/omx/1.0/OmxStore.h>
-
-// This is created by module "codec2.vendor.base.policy". This can be modified.
+// This is the absolute on-device path of the prebuild_etc module
+// "android.hardware.media.c2@1.1-default-seccomp_policy" in Android.bp.
static constexpr char kBaseSeccompPolicyPath[] =
- "/vendor/etc/seccomp_policy/codec2.vendor.base.policy";
+ "/vendor/etc/seccomp_policy/"
+ "android.hardware.media.c2@1.1-default-seccomp-policy";
-// Additional device-specific seccomp permissions can be added in this file.
+// Additional seccomp permissions can be added in this file.
+// This file does not exist by default.
static constexpr char kExtSeccompPolicyPath[] =
- "/vendor/etc/seccomp_policy/codec2.vendor.ext.policy";
+ "/vendor/etc/seccomp_policy/"
+ "android.hardware.media.c2@1.1-extended-seccomp-policy";
class DummyC2Store : public C2ComponentStore {
public:
@@ -97,54 +99,48 @@
};
int main(int /* argc */, char** /* argv */) {
- ALOGD("android.hardware.media.c2@1.0-service starting...");
+ using namespace ::android;
+ LOG(DEBUG) << "android.hardware.media.c2@1.1-service starting...";
+ // Set up minijail to limit system calls.
signal(SIGPIPE, SIG_IGN);
- android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
+ SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
- // vndbinder is needed by BufferQueue.
- android::ProcessState::initWithDriver("/dev/vndbinder");
- android::ProcessState::self()->startThreadPool();
+ // Enable vndbinder to allow vendor-to-vendor binder calls.
+ ProcessState::initWithDriver("/dev/vndbinder");
+ ProcessState::self()->startThreadPool();
// Extra threads may be needed to handle a stacked IPC sequence that
// contains alternating binder and hwbinder calls. (See b/35283480.)
- android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
+ hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
// Create IComponentStore service.
{
- using namespace ::android::hardware::media::c2::V1_0;
- android::sp<IComponentStore> store;
+ using namespace ::android::hardware::media::c2::V1_1;
+ sp<IComponentStore> store;
- // Vendor's TODO: Replace this with
+ // TODO: Replace this with
// store = new utils::ComponentStore(
// /* implementation of C2ComponentStore */);
- ALOGD("Instantiating Codec2's dummy IComponentStore service...");
+ LOG(DEBUG) << "Instantiating Codec2's IComponentStore service...";
store = new utils::ComponentStore(
std::make_shared<DummyC2Store>());
if (store == nullptr) {
- ALOGE("Cannot create Codec2's IComponentStore service.");
+ LOG(ERROR) << "Cannot create Codec2's IComponentStore service.";
} else {
- if (store->registerAsService("default") != android::OK) {
- ALOGE("Cannot register Codec2's "
- "IComponentStore service.");
+ constexpr char const* serviceName = "default";
+ if (store->registerAsService(serviceName) != OK) {
+ LOG(ERROR) << "Cannot register Codec2's IComponentStore service"
+ " with instance name << \""
+ << serviceName << "\".";
} else {
- ALOGI("Codec2's IComponentStore service created.");
+ LOG(DEBUG) << "Codec2's IComponentStore service registered. "
+ "Instance name: \"" << serviceName << "\".";
}
}
}
- // Register IOmxStore service.
- {
- using namespace ::android::hardware::media::omx::V1_0;
- android::sp<IOmxStore> omxStore = new implementation::OmxStore();
- if (omxStore == nullptr) {
- ALOGE("Cannot create IOmxStore HAL service.");
- } else if (omxStore->registerAsService() != android::OK) {
- ALOGE("Cannot register IOmxStore HAL service.");
- }
- }
-
- android::hardware::joinRpcThreadpool();
+ hardware::joinRpcThreadpool();
return 0;
}
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 1cbbbb8..c78cdc1 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -27,6 +27,7 @@
#include <C2PlatformSupport.h>
#include <android/IOMXBufferSource.h>
+#include <android/hardware/media/c2/1.0/IInputSurface.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android-base/stringprintf.h>
diff --git a/media/libdatasource/NuCachedSource2.cpp b/media/libdatasource/NuCachedSource2.cpp
index 7f5ae61..6d63ffb 100644
--- a/media/libdatasource/NuCachedSource2.cpp
+++ b/media/libdatasource/NuCachedSource2.cpp
@@ -689,10 +689,6 @@
restartPrefetcherIfNecessary_l(true /* ignore low water threshold */);
}
-sp<DecryptHandle> NuCachedSource2::DrmInitialization(const char* mime) {
- return mSource->DrmInitialization(mime);
-}
-
String8 NuCachedSource2::getUri() {
return mSource->getUri();
}
diff --git a/media/libdatasource/include/datasource/NuCachedSource2.h b/media/libdatasource/include/datasource/NuCachedSource2.h
index 596efb8..4c253ad 100644
--- a/media/libdatasource/include/datasource/NuCachedSource2.h
+++ b/media/libdatasource/include/datasource/NuCachedSource2.h
@@ -44,7 +44,6 @@
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
- virtual sp<DecryptHandle> DrmInitialization(const char* mime);
virtual String8 getUri();
virtual String8 getMIMEType() const;
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 33ea1ca..b80f4b4 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -83,9 +83,6 @@
void close() {}
uint32_t getFlags() override { return 0; }
String8 toString() override { return String8("HeifDataSource"); }
- sp<DecryptHandle> DrmInitialization(const char*) override {
- return nullptr;
- }
private:
enum {
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index ac88448..b064f08 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -34,7 +34,6 @@
"aidl/android/media/MediaResourceParcel.aidl",
"aidl/android/media/MediaResourcePolicyParcel.aidl",
],
- api_dir: "api/resourcemanager",
versions: ["1"],
}
diff --git a/media/libmedia/IDataSource.cpp b/media/libmedia/IDataSource.cpp
index 31c85af..61f0a68 100644
--- a/media/libmedia/IDataSource.cpp
+++ b/media/libmedia/IDataSource.cpp
@@ -23,7 +23,6 @@
#include <binder/IMemory.h>
#include <binder/Parcel.h>
-#include <drm/drm_framework_common.h>
#include <media/stagefright/foundation/ADebug.h>
namespace android {
@@ -35,7 +34,6 @@
CLOSE,
GET_FLAGS,
TO_STRING,
- DRM_INITIALIZATION,
};
struct BpDataSource : public BpInterface<IDataSource> {
@@ -95,47 +93,6 @@
remote()->transact(TO_STRING, data, &reply);
return reply.readString8();
}
-
- virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
- Parcel data, reply;
- data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
- if (mime == NULL) {
- data.writeInt32(0);
- } else {
- data.writeInt32(1);
- data.writeCString(mime);
- }
- remote()->transact(DRM_INITIALIZATION, data, &reply);
- sp<DecryptHandle> handle;
- if (reply.dataAvail() != 0) {
- handle = new DecryptHandle();
- handle->decryptId = reply.readInt32();
- handle->mimeType = reply.readString8();
- handle->decryptApiType = reply.readInt32();
- handle->status = reply.readInt32();
-
- const int bufferLength = data.readInt32();
- if (bufferLength != -1) {
- handle->decryptInfo = new DecryptInfo();
- handle->decryptInfo->decryptBufferLength = bufferLength;
- }
-
- size_t size = data.readInt32();
- for (size_t i = 0; i < size; ++i) {
- DrmCopyControl key = (DrmCopyControl)data.readInt32();
- int value = data.readInt32();
- handle->copyControlVector.add(key, value);
- }
-
- size = data.readInt32();
- for (size_t i = 0; i < size; ++i) {
- String8 key = data.readString8();
- String8 value = data.readString8();
- handle->extendedData.add(key, value);
- }
- }
- return handle;
- }
};
IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
@@ -178,42 +135,6 @@
reply->writeString8(toString());
return NO_ERROR;
} break;
- case DRM_INITIALIZATION: {
- CHECK_INTERFACE(IDataSource, data, reply);
- const char *mime = NULL;
- const int32_t flag = data.readInt32();
- if (flag != 0) {
- mime = data.readCString();
- }
- sp<DecryptHandle> handle = DrmInitialization(mime);
- if (handle != NULL) {
- reply->writeInt32(handle->decryptId);
- reply->writeString8(handle->mimeType);
- reply->writeInt32(handle->decryptApiType);
- reply->writeInt32(handle->status);
-
- if (handle->decryptInfo != NULL) {
- reply->writeInt32(handle->decryptInfo->decryptBufferLength);
- } else {
- reply->writeInt32(-1);
- }
-
- size_t size = handle->copyControlVector.size();
- reply->writeInt32(size);
- for (size_t i = 0; i < size; ++i) {
- reply->writeInt32(handle->copyControlVector.keyAt(i));
- reply->writeInt32(handle->copyControlVector.valueAt(i));
- }
-
- size = handle->extendedData.size();
- reply->writeInt32(size);
- for (size_t i = 0; i < size; ++i) {
- reply->writeString8(handle->extendedData.keyAt(i));
- reply->writeString8(handle->extendedData.valueAt(i));
- }
- }
- return NO_ERROR;
- } break;
default:
return BBinder::onTransact(code, data, reply, flags);
diff --git a/media/libmedia/api/resourcemanager/1/.hash b/media/libmedia/aidl_api/resourcemanager_aidl_interface/.hash
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/.hash
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/.hash
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerClient.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerClient.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerService.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerService.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceParcel.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceParcel.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourcePolicyParcel.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourcePolicyParcel.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceSubType.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceSubType.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceType.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceType.aidl
diff --git a/media/libmedia/include/media/IDataSource.h b/media/libmedia/include/media/IDataSource.h
index 3858f78..43e2b50 100644
--- a/media/libmedia/include/media/IDataSource.h
+++ b/media/libmedia/include/media/IDataSource.h
@@ -50,8 +50,6 @@
virtual uint32_t getFlags() = 0;
// get a description of the source, e.g. the url or filename it is based on
virtual String8 toString() = 0;
- // Initialize DRM and return a DecryptHandle.
- virtual sp<DecryptHandle> DrmInitialization(const char *mime) = 0;
private:
DISALLOW_EVIL_CONSTRUCTORS(IDataSource);
diff --git a/media/libmediametrics/TEST_MAPPING b/media/libmediametrics/TEST_MAPPING
new file mode 100644
index 0000000..01e9e46
--- /dev/null
+++ b/media/libmediametrics/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+ "presubmit": [
+ {
+ "name": "mediametrics_tests"
+ },
+ {
+ "name": "CtsNativeMediaMetricsTestCases"
+ }
+ ]
+}
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
index 1580891..bb4ba75 100644
--- a/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
+++ b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
@@ -31,6 +31,7 @@
mDrmBufOffset(0),
mDrmBufSize(0),
mDrmBuf(NULL){
+ (void) DrmInitialization(nullptr);
}
PlayerServiceFileSource::PlayerServiceFileSource(int fd, int64_t offset, int64_t length)
@@ -40,6 +41,7 @@
mDrmBufOffset(0),
mDrmBufSize(0),
mDrmBuf(NULL) {
+ (void) DrmInitialization(nullptr);
}
PlayerServiceFileSource::~PlayerServiceFileSource() {
@@ -87,7 +89,9 @@
}
sp<DecryptHandle> PlayerServiceFileSource::DrmInitialization(const char *mime) {
- if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
+ if (getuid() == AID_MEDIA_EX) {
+ return NULL; // no DRM in media extractor
+ }
if (mDrmManagerClient == NULL) {
mDrmManagerClient = new DrmManagerClient();
}
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
index 0124720..f99a861 100644
--- a/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
+++ b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
@@ -32,6 +32,7 @@
PlayerServiceMediaHTTP::PlayerServiceMediaHTTP(const sp<MediaHTTPConnection> &conn)
: MediaHTTP(conn),
mDrmManagerClient(NULL) {
+ (void) DrmInitialization(nullptr);
}
PlayerServiceMediaHTTP::~PlayerServiceMediaHTTP() {
@@ -40,7 +41,7 @@
// DRM...
-sp<DecryptHandle> PlayerServiceMediaHTTP::DrmInitialization(const char* mime) {
+sp<DecryptHandle> PlayerServiceMediaHTTP::DrmInitialization(const char *mime) {
if (mDrmManagerClient == NULL) {
mDrmManagerClient = new DrmManagerClient();
}
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
index 08a013e..7ae8dda 100644
--- a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
@@ -37,8 +37,6 @@
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
- virtual sp<DecryptHandle> DrmInitialization(const char *mime);
-
static bool requiresDrm(int fd, int64_t offset, int64_t length, const char *mime);
protected:
@@ -52,6 +50,7 @@
ssize_t mDrmBufSize;
unsigned char *mDrmBuf;
+ sp<DecryptHandle> DrmInitialization(const char *mime);
ssize_t readAtDRM_l(off64_t offset, void *data, size_t size);
PlayerServiceFileSource(const PlayerServiceFileSource &);
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
index 0032cd7..b5124dc 100644
--- a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
@@ -33,12 +33,11 @@
protected:
virtual ~PlayerServiceMediaHTTP();
- virtual sp<DecryptHandle> DrmInitialization(const char* mime);
-
private:
sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
+ sp<DecryptHandle> DrmInitialization(const char *mime);
void clearDRMState_l();
DISALLOW_EVIL_CONSTRUCTORS(PlayerServiceMediaHTTP);
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index 2f8e6af..dea83d4 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -114,10 +114,6 @@
}
}
-sp<DecryptHandle> CallbackDataSource::DrmInitialization(const char *mime) {
- return mIDataSource->DrmInitialization(mime);
-}
-
sp<IDataSource> CallbackDataSource::getIDataSource() const {
return mIDataSource;
}
@@ -191,14 +187,6 @@
return mSource->flags();
}
-sp<DecryptHandle> TinyCacheSource::DrmInitialization(const char *mime) {
- // flush cache when DrmInitialization occurs since decrypted
- // data may differ from what is in cache.
- mCachedOffset = 0;
- mCachedSize = 0;
- return mSource->DrmInitialization(mime);
-}
-
sp<IDataSource> TinyCacheSource::getIDataSource() const {
return mSource->getIDataSource();
}
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 4c8be1f..120f354 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -71,9 +71,6 @@
ALOGV("MediaExtractorFactory::CreateFromService %s", mime);
- // initialize source decryption if needed
- source->DrmInitialization(nullptr /* mime */);
-
void *meta = nullptr;
void *creator = NULL;
FreeMetaFunc freeMeta = nullptr;
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 9f413cd..e428494 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -41,7 +41,6 @@
virtual String8 toString() {
return mName;
}
- virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
virtual sp<IDataSource> getIDataSource() const;
private:
@@ -70,7 +69,6 @@
virtual String8 toString() {
return mName;
}
- virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
virtual sp<IDataSource> getIDataSource() const;
private:
diff --git a/media/libstagefright/include/ThrottledSource.h b/media/libstagefright/include/ThrottledSource.h
index 71e62f7..5ae0653 100644
--- a/media/libstagefright/include/ThrottledSource.h
+++ b/media/libstagefright/include/ThrottledSource.h
@@ -54,10 +54,6 @@
return mSource->reconnectAtOffset(offset);
}
- virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL) {
- return mSource->DrmInitialization(mime);
- }
-
virtual String8 getMIMEType() const {
return mSource->getMIMEType();
}
diff --git a/media/libstagefright/include/media/stagefright/DataSource.h b/media/libstagefright/include/media/stagefright/DataSource.h
index 1f7a473..83d3e5d 100644
--- a/media/libstagefright/include/media/stagefright/DataSource.h
+++ b/media/libstagefright/include/media/stagefright/DataSource.h
@@ -52,11 +52,6 @@
////////////////////////////////////////////////////////////////////////////
- // for DRM
- virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
- return NULL;
- }
-
virtual String8 getUri() {
return String8();
}
diff --git a/media/libstagefright/include/media/stagefright/RemoteDataSource.h b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
index b634505..83273cb 100644
--- a/media/libstagefright/include/media/stagefright/RemoteDataSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
@@ -66,9 +66,6 @@
virtual String8 toString() {
return mName;
}
- virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
- return mSource->DrmInitialization(mime);
- }
private:
enum {
diff --git a/media/libstagefright/tests/writer/Android.bp b/media/libstagefright/tests/writer/Android.bp
new file mode 100644
index 0000000..7e169cb
--- /dev/null
+++ b/media/libstagefright/tests/writer/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "writerTest",
+ gtest: true,
+
+ srcs: [
+ "WriterUtility.cpp",
+ "WriterTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libstagefright_webm",
+ "libdatasource",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libstagefright_esds",
+ "libogg",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/tests/writer/README.md b/media/libstagefright/tests/writer/README.md
new file mode 100644
index 0000000..52db6f0
--- /dev/null
+++ b/media/libstagefright/tests/writer/README.md
@@ -0,0 +1,30 @@
+## Media Testing ##
+---
+#### Writer :
+The Writer Test Suite validates the writers available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+mmm frameworks/av/media/libstagefright/tests/writer/
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+
+adb push ${OUT}/data/nativetest64/writerTest/writerTest /data/local/tmp/
+
+To test 32-bit binary push binaries from nativetest.
+
+adb push ${OUT}/data/nativetest/writerTest/writerTest /data/local/tmp/
+
+The resource file for the tests is taken from Codec2 VTS resource folder. Push these files into device for testing.
+```
+adb push $ANDROID_BUILD_TOP/frameworks/av/media/codec2/hidl/1.0/vts/functional/res /sdcard/
+```
+
+usage: writerTest -P \<path_to_res_folder\>
+```
+adb shell /data/local/tmp/writerTest -P /sdcard/res/
+```
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
new file mode 100644
index 0000000..d68438c
--- /dev/null
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "WriterTest"
+#include <utils/Log.h>
+
+#include <fstream>
+#include <iostream>
+
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+#include <media/mediarecorder.h>
+
+#include <media/stagefright/AACWriter.h>
+#include <media/stagefright/AMRWriter.h>
+#include <media/stagefright/OggWriter.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/MPEG2TSWriter.h>
+#include <webm/WebmWriter.h>
+
+#include "WriterTestEnvironment.h"
+#include "WriterUtility.h"
+
+#define OUTPUT_FILE_NAME "/data/local/tmp/writer.out"
+
+static WriterTestEnvironment *gEnv = nullptr;
+
+struct configFormat {
+ char mime[128];
+ int32_t width;
+ int32_t height;
+ int32_t sampleRate;
+ int32_t channelCount;
+};
+
+// LookUpTable of clips and metadata for component testing
+static const struct InputData {
+ const char *mime;
+ string inputFile;
+ string info;
+ int32_t firstParam;
+ int32_t secondParam;
+ bool isAudio;
+} kInputData[] = {
+ {MEDIA_MIMETYPE_AUDIO_OPUS, "bbb_opus_stereo_128kbps_48000hz.opus",
+ "bbb_opus_stereo_128kbps_48000hz.info", 48000, 2, true},
+ {MEDIA_MIMETYPE_AUDIO_AAC, "bbb_aac_stereo_128kbps_48000hz.aac",
+ "bbb_aac_stereo_128kbps_48000hz.info", 48000, 2, true},
+ {MEDIA_MIMETYPE_AUDIO_AAC_ADTS, "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.adts",
+ "Mps_2_c2_fr1_Sc1_Dc2_0x03_raw.info", 48000, 2, true},
+ {MEDIA_MIMETYPE_AUDIO_AMR_NB, "sine_amrnb_1ch_12kbps_8000hz.amrnb",
+ "sine_amrnb_1ch_12kbps_8000hz.info", 8000, 1, true},
+ {MEDIA_MIMETYPE_AUDIO_AMR_WB, "bbb_amrwb_1ch_14kbps_16000hz.amrwb",
+ "bbb_amrwb_1ch_14kbps_16000hz.info", 16000, 1, true},
+ {MEDIA_MIMETYPE_AUDIO_VORBIS, "bbb_vorbis_stereo_128kbps_48000hz.vorbis",
+ "bbb_vorbis_stereo_128kbps_48000hz.info", 48000, 2, true},
+ {MEDIA_MIMETYPE_AUDIO_FLAC, "bbb_flac_stereo_680kbps_48000hz.flac",
+ "bbb_flac_stereo_680kbps_48000hz.info", 48000, 2, true},
+ {MEDIA_MIMETYPE_VIDEO_VP9, "bbb_vp9_176x144_285kbps_60fps.vp9",
+ "bbb_vp9_176x144_285kbps_60fps.info", 176, 144, false},
+ {MEDIA_MIMETYPE_VIDEO_VP8, "bbb_vp8_176x144_240kbps_60fps.vp8",
+ "bbb_vp8_176x144_240kbps_60fps.info", 176, 144, false},
+ {MEDIA_MIMETYPE_VIDEO_AVC, "bbb_avc_176x144_300kbps_60fps.h264",
+ "bbb_avc_176x144_300kbps_60fps.info", 176, 144, false},
+ {MEDIA_MIMETYPE_VIDEO_HEVC, "bbb_hevc_176x144_176kbps_60fps.hevc",
+ "bbb_hevc_176x144_176kbps_60fps.info", 176, 144, false},
+ {MEDIA_MIMETYPE_VIDEO_AV1, "bbb_av1_176_144.av1", "bbb_av1_176_144.info", 176, 144, false},
+ {MEDIA_MIMETYPE_VIDEO_H263, "bbb_h263_352x288_300kbps_12fps.h263",
+ "bbb_h263_352x288_300kbps_12fps.info", 352, 288, false},
+ {MEDIA_MIMETYPE_VIDEO_MPEG4, "bbb_mpeg4_352x288_512kbps_30fps.m4v",
+ "bbb_mpeg4_352x288_512kbps_30fps.info", 352, 288, false},
+};
+
+class WriterTest : public ::testing::TestWithParam<pair<string, int32_t>> {
+ public:
+ virtual void SetUp() override {
+ mNumCsds = 0;
+ mInputFrameId = 0;
+ mWriterName = unknown_comp;
+ mDisableTest = false;
+
+ std::map<std::string, standardWriters> mapWriter = {
+ {"ogg", OGG}, {"aac", AAC}, {"aac_adts", AAC_ADTS}, {"webm", WEBM},
+ {"mpeg4", MPEG4}, {"amrnb", AMR_NB}, {"amrwb", AMR_WB}, {"mpeg2Ts", MPEG2TS}};
+ // Find the component type
+ string writerFormat = GetParam().first;
+ if (mapWriter.find(writerFormat) != mapWriter.end()) {
+ mWriterName = mapWriter[writerFormat];
+ }
+ if (mWriterName == standardWriters::unknown_comp) {
+ cout << "[ WARN ] Test Skipped. No specific writer mentioned\n";
+ mDisableTest = true;
+ }
+ }
+
+ virtual void TearDown() override {
+ mWriter.clear();
+ mFileMeta.clear();
+ mBufferInfo.clear();
+ if (mInputStream) mInputStream.close();
+ }
+
+ void getInputBufferInfo(string inputFileName, string inputInfo);
+
+ int32_t createWriter(int32_t fd);
+
+ int32_t addWriterSource(bool isAudio, configFormat params);
+
+ enum standardWriters {
+ OGG,
+ AAC,
+ AAC_ADTS,
+ WEBM,
+ MPEG4,
+ AMR_NB,
+ AMR_WB,
+ MPEG2TS,
+ unknown_comp,
+ };
+
+ standardWriters mWriterName;
+ sp<MediaWriter> mWriter;
+ sp<MetaData> mFileMeta;
+ sp<MediaAdapter> mCurrentTrack;
+
+ bool mDisableTest;
+ int32_t mNumCsds;
+ int32_t mInputFrameId;
+ ifstream mInputStream;
+ vector<BufferInfo> mBufferInfo;
+};
+
+void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo) {
+ std::ifstream eleInfo;
+ eleInfo.open(inputInfo.c_str());
+ CHECK_EQ(eleInfo.is_open(), true);
+ int32_t bytesCount = 0;
+ uint32_t flags = 0;
+ int64_t timestamp = 0;
+ while (1) {
+ if (!(eleInfo >> bytesCount)) break;
+ eleInfo >> flags;
+ eleInfo >> timestamp;
+ mBufferInfo.push_back({bytesCount, flags, timestamp});
+ if (flags == CODEC_CONFIG_FLAG) mNumCsds++;
+ }
+ eleInfo.close();
+ mInputStream.open(inputFileName.c_str(), std::ifstream::binary);
+ CHECK_EQ(mInputStream.is_open(), true);
+}
+
+int32_t WriterTest::createWriter(int32_t fd) {
+ mFileMeta = new MetaData;
+ switch (mWriterName) {
+ case OGG:
+ mWriter = new OggWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_OGG);
+ break;
+ case AAC:
+ mWriter = new AACWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AAC_ADIF);
+ break;
+ case AAC_ADTS:
+ mWriter = new AACWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AAC_ADTS);
+ break;
+ case WEBM:
+ mWriter = new WebmWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_WEBM);
+ break;
+ case MPEG4:
+ mWriter = new MPEG4Writer(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG_4);
+ break;
+ case AMR_NB:
+ mWriter = new AMRWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_NB);
+ break;
+ case AMR_WB:
+ mWriter = new AMRWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_WB);
+ break;
+ case MPEG2TS:
+ mWriter = new MPEG2TSWriter(fd);
+ mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG2TS);
+ break;
+ default:
+ return -1;
+ }
+ if (mWriter == nullptr) return -1;
+ mFileMeta->setInt32(kKeyRealTimeRecording, false);
+ return 0;
+}
+
+int32_t WriterTest::addWriterSource(bool isAudio, configFormat params) {
+ if (mInputFrameId) return -1;
+ sp<AMessage> format = new AMessage;
+ if (mInputStream.is_open()) {
+ format->setString("mime", params.mime);
+ if (isAudio) {
+ format->setInt32("channel-count", params.channelCount);
+ format->setInt32("sample-rate", params.sampleRate);
+ } else {
+ format->setInt32("width", params.width);
+ format->setInt32("height", params.height);
+ }
+
+ int32_t status =
+ writeHeaderBuffers(mInputStream, mBufferInfo, mInputFrameId, format, mNumCsds);
+ if (status != 0) return -1;
+ }
+ sp<MetaData> trackMeta = new MetaData;
+ convertMessageToMetaData(format, trackMeta);
+ mCurrentTrack = new MediaAdapter(trackMeta);
+ status_t result = mWriter->addSource(mCurrentTrack);
+ return result;
+}
+
+void getFileDetails(string &inputFilePath, string &info, configFormat ¶ms, bool &isAudio,
+ int32_t streamIndex = 0) {
+ if (streamIndex >= sizeof(kInputData) / sizeof(kInputData[0])) {
+ return;
+ }
+ inputFilePath += kInputData[streamIndex].inputFile;
+ info += kInputData[streamIndex].info;
+ strcpy(params.mime, kInputData[streamIndex].mime);
+ isAudio = kInputData[streamIndex].isAudio;
+ if (isAudio) {
+ params.sampleRate = kInputData[streamIndex].firstParam;
+ params.channelCount = kInputData[streamIndex].secondParam;
+ } else {
+ params.width = kInputData[streamIndex].firstParam;
+ params.height = kInputData[streamIndex].secondParam;
+ }
+ return;
+}
+
+TEST_P(WriterTest, CreateWriterTest) {
+ if (mDisableTest) return;
+ ALOGV("Tests the creation of writers");
+
+ string outputFile = OUTPUT_FILE_NAME;
+ int32_t fd =
+ open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd < 0) return;
+
+ // Creating writer within a test scope. Destructor should be called when the test ends
+ int32_t status = createWriter(fd);
+ if (status) {
+ cout << "Failed to create writer for output format:" << GetParam().first << "\n";
+ ASSERT_TRUE(false);
+ }
+}
+
+TEST_P(WriterTest, WriterTest) {
+ if (mDisableTest) return;
+ ALOGV("Checks if for a given input, a valid muxed file has been created or not");
+
+ string writerFormat = GetParam().first;
+ string outputFile = OUTPUT_FILE_NAME;
+ int32_t fd =
+ open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd < 0) return;
+ int32_t status = createWriter(fd);
+ if (status) {
+ cout << "Failed to create writer for output format:" << writerFormat << "\n";
+ ASSERT_TRUE(false);
+ }
+ string inputFile = gEnv->getRes();
+ string inputInfo = gEnv->getRes();
+ configFormat param;
+ bool isAudio;
+ int32_t inputFileIdx = GetParam().second;
+ getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+ if (!inputFile.compare(gEnv->getRes())) {
+ ALOGV("No input file specified");
+ return;
+ }
+ getInputBufferInfo(inputFile, inputInfo);
+ status = addWriterSource(isAudio, param);
+ if (status) {
+ cout << "Failed to add source for " << writerFormat << "Writer \n";
+ ASSERT_TRUE(false);
+ }
+ CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
+ mBufferInfo.size());
+ mCurrentTrack->stop();
+ if (status) {
+ cout << writerFormat << " writer failed \n";
+ mWriter->stop();
+ ASSERT_TRUE(false);
+ }
+ CHECK_EQ((status_t)OK, mWriter->stop());
+ close(fd);
+}
+
+TEST_P(WriterTest, PauseWriterTest) {
+ if (mDisableTest) return;
+ ALOGV("Validates the pause() api of writers");
+
+ string writerFormat = GetParam().first;
+ string outputFile = OUTPUT_FILE_NAME;
+ int32_t fd =
+ open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd < 0) return;
+ int32_t status = createWriter(fd);
+ if (status) {
+ cout << "Failed to create writer for output format:" << writerFormat << "\n";
+ ASSERT_TRUE(false);
+ }
+ string inputFile = gEnv->getRes();
+ string inputInfo = gEnv->getRes();
+ configFormat param;
+ bool isAudio;
+ int32_t inputFileIdx = GetParam().second;
+ getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+ if (!inputFile.compare(gEnv->getRes())) {
+ ALOGV("No input file specified");
+ return;
+ }
+ getInputBufferInfo(inputFile, inputInfo);
+ status = addWriterSource(isAudio, param);
+ if (status) {
+ cout << "Failed to add source for " << writerFormat << "Writer \n";
+ ASSERT_TRUE(false);
+ }
+ CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
+ mBufferInfo.size() / 4);
+ if (status) {
+ cout << writerFormat << " writer failed \n";
+ mCurrentTrack->stop();
+ mWriter->stop();
+ ASSERT_TRUE(false);
+ }
+
+ bool isPaused = false;
+ if ((mWriterName != standardWriters::MPEG2TS) && (mWriterName != standardWriters::MPEG4)) {
+ CHECK_EQ((status_t)OK, mWriter->pause());
+ isPaused = true;
+ }
+ // In the pause state, writers shouldn't write anything. Testing the writers for the same
+ int32_t numFramesPaused = mBufferInfo.size() / 4;
+ status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ mInputFrameId, numFramesPaused, isPaused);
+ if (isPaused) {
+ CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ }
+ status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ mInputFrameId, mBufferInfo.size());
+ mCurrentTrack->stop();
+ if (status) {
+ cout << writerFormat << " writer failed \n";
+ mWriter->stop();
+ ASSERT_TRUE(false);
+ }
+ CHECK_EQ((status_t)OK, mWriter->stop());
+ close(fd);
+}
+
+// TODO: (b/144476164)
+// Add AAC_ADTS, FLAC, AV1 input
+INSTANTIATE_TEST_SUITE_P(WriterTestAll, WriterTest,
+ ::testing::Values(make_pair("ogg", 0), make_pair("webm", 0),
+ make_pair("aac", 1), make_pair("mpeg4", 1),
+ make_pair("amrnb", 3), make_pair("amrwb", 4),
+ make_pair("webm", 5), make_pair("webm", 7),
+ make_pair("webm", 8), make_pair("mpeg4", 9),
+ make_pair("mpeg4", 10), make_pair("mpeg4", 12),
+ make_pair("mpeg4", 13), make_pair("mpeg2Ts", 1),
+ make_pair("mpeg2Ts", 9)));
+
+int main(int argc, char **argv) {
+ gEnv = new WriterTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ }
+ return status;
+}
diff --git a/media/libstagefright/tests/writer/WriterTestEnvironment.h b/media/libstagefright/tests/writer/WriterTestEnvironment.h
new file mode 100644
index 0000000..34c2baa
--- /dev/null
+++ b/media/libstagefright/tests/writer/WriterTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WRITER_TEST_ENVIRONMENT_H__
+#define __WRITER_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class WriterTestEnvironment : public ::testing::Environment {
+ public:
+ WriterTestEnvironment() : res("/sdcard/media/") {}
+
+ // Parses the command line arguments
+ int initFromOptions(int argc, char **argv);
+
+ void setRes(const char *_res) { res = _res; }
+
+ const string getRes() const { return res; }
+
+ private:
+ string res;
+};
+
+int WriterTestEnvironment::initFromOptions(int argc, char **argv) {
+ static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "P:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'P':
+ setRes(optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-P, --path: Resource files directory location\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+}
+
+#endif // __WRITER_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/writer/WriterUtility.cpp b/media/libstagefright/tests/writer/WriterUtility.cpp
new file mode 100644
index 0000000..2ba90a0
--- /dev/null
+++ b/media/libstagefright/tests/writer/WriterUtility.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "WriterUtility"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaBuffer.h>
+
+#include "WriterUtility.h"
+
+int32_t sendBuffersToWriter(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
+ int32_t &inputFrameId, sp<MediaAdapter> ¤tTrack, int32_t offset,
+ int32_t range, bool isPaused) {
+ while (1) {
+ if (inputFrameId == (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
+ int32_t size = bufferInfo[inputFrameId].size;
+ char *data = (char *)malloc(size);
+ if (!data) {
+ ALOGE("Insufficient memeory to read input");
+ return -1;
+ }
+
+ inputStream.read(data, size);
+ CHECK_EQ(inputStream.gcount(), size);
+
+ sp<ABuffer> buffer = new ABuffer((void *)data, size);
+ if (buffer.get() == nullptr) {
+ ALOGE("sendBuffersToWriter() got a nullptr buffer.");
+ return -1;
+ }
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+
+ // Released in MediaAdapter::signalBufferReturned().
+ mediaBuffer->add_ref();
+ mediaBuffer->set_range(buffer->offset(), buffer->size());
+
+ MetaDataBase &sampleMetaData = mediaBuffer->meta_data();
+ sampleMetaData.setInt64(kKeyTime, bufferInfo[inputFrameId].timeUs);
+ // Just set the kKeyDecodingTime as the presentation time for now.
+ sampleMetaData.setInt64(kKeyDecodingTime, bufferInfo[inputFrameId].timeUs);
+
+ if (bufferInfo[inputFrameId].flags == 1) {
+ sampleMetaData.setInt32(kKeyIsSyncFrame, true);
+ }
+
+ // This pushBuffer will wait until the mediaBuffer is consumed.
+ int status = currentTrack->pushBuffer(mediaBuffer);
+ free(data);
+ inputFrameId++;
+
+ if (OK != status) {
+ if (!isPaused) return status;
+ else {
+ ALOGD("Writer is in paused state. Input buffers won't get consumed");
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+int32_t writeHeaderBuffers(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
+ int32_t &inputFrameId, sp<AMessage> &format, int32_t numCsds) {
+ char csdName[kMaxCSDStrlen];
+ for (int csdId = 0; csdId < numCsds; csdId++) {
+ int32_t flags = bufferInfo[inputFrameId].flags;
+ if (flags == CODEC_CONFIG_FLAG) {
+ int32_t size = bufferInfo[inputFrameId].size;
+ char *data = (char *)malloc(size);
+ if (!data) {
+ ALOGE("Insufficient memeory to read input");
+ return -1;
+ }
+ inputStream.read(data, size);
+ CHECK_EQ(inputStream.gcount(), size);
+
+ sp<ABuffer> csdBuffer = ABuffer::CreateAsCopy((void *)data, size);
+ if (csdBuffer.get() == nullptr || csdBuffer->base() == nullptr) {
+ return -1;
+ }
+ snprintf(csdName, sizeof(csdName), "csd-%d", csdId);
+ format->setBuffer(csdName, csdBuffer);
+ inputFrameId++;
+ free(data);
+ }
+ }
+ return 0;
+}
diff --git a/media/libstagefright/tests/writer/WriterUtility.h b/media/libstagefright/tests/writer/WriterUtility.h
new file mode 100644
index 0000000..d402798
--- /dev/null
+++ b/media/libstagefright/tests/writer/WriterUtility.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WRITER_UTILITY_H_
+#define WRITER_UTILITY_H_
+
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <media/stagefright/MediaAdapter.h>
+
+using namespace android;
+using namespace std;
+
+#define CODEC_CONFIG_FLAG 32
+
+constexpr uint32_t kMaxCSDStrlen = 16;
+
+struct BufferInfo {
+ int32_t size;
+ uint32_t flags;
+ int64_t timeUs;
+};
+
+int32_t sendBuffersToWriter(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
+ int32_t &inputFrameId, sp<MediaAdapter> ¤tTrack, int32_t offset,
+ int32_t range, bool isPaused = false);
+
+int32_t writeHeaderBuffers(ifstream &inputStream, vector<BufferInfo> &bufferInfo,
+ int32_t &inputFrameId, sp<AMessage> &format, int32_t numCsds);
+
+#endif // WRITER_UTILITY_H_
diff --git a/media/mediaserver/manifest_media_c2_software.xml b/media/mediaserver/manifest_media_c2_software.xml
index 5196336..f23ed44 100644
--- a/media/mediaserver/manifest_media_c2_software.xml
+++ b/media/mediaserver/manifest_media_c2_software.xml
@@ -2,7 +2,7 @@
<hal>
<name>android.hardware.media.c2</name>
<transport>hwbinder</transport>
- <version>1.0</version>
+ <version>1.1</version>
<interface>
<name>IComponentStore</name>
<instance>software</instance>
diff --git a/media/mediaserver/mediaserver.rc b/media/mediaserver/mediaserver.rc
index f6c325c..ecb75a9 100644
--- a/media/mediaserver/mediaserver.rc
+++ b/media/mediaserver/mediaserver.rc
@@ -1,3 +1,6 @@
+on property:init.svc.media=*
+ setprop init.svc.mediadrm ${init.svc.media}
+
service media /system/bin/mediaserver
class main
user media
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
index 5bdb48a..ab74508 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
@@ -56,10 +56,10 @@
void OnErrorCB(AMediaCodec *codec, void *userdata, media_status_t err, int32_t actionCode,
const char *detail) {
- (void)codec;
- ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
+ ALOGE("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
CallBackHandle *self = (CallBackHandle *)userdata;
self->mSawError = true;
+ self->mIOQueue.push([self, codec, err]() { self->onError(codec, err); });
}
AMediaCodec *createMediaCodec(AMediaFormat *format, const char *mime, string codecName,
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
index 15749f0..8153a86 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.h
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -87,6 +87,10 @@
(void)codec;
(void)format;
}
+ virtual void onError(AMediaCodec *codec, media_status_t err) {
+ (void)codec;
+ (void)err;
+ }
virtual void onOutputAvailable(AMediaCodec *codec, int32_t index,
AMediaCodecBufferInfo *bufferInfo) {
(void)codec;
diff --git a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
index e88d011..20a1468 100644
--- a/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/C2Decoder.cpp
@@ -16,8 +16,10 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2Decoder"
+#include <log/log.h>
#include "C2Decoder.h"
+#include <iostream>
int32_t C2Decoder::createCodec2Component(string compName, AMediaFormat *format) {
ALOGV("In %s", __func__);
@@ -87,7 +89,7 @@
work.swap(mWorkQueue.front());
mWorkQueue.pop_front();
} else {
- cout << "Wait for generating C2Work exceeded timeout" << endl;
+ std::cout << "Wait for generating C2Work exceeded timeout" << std::endl;
return -1;
}
}
@@ -110,13 +112,13 @@
status = mLinearPool->fetchLinearBlock(
alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
if (status != C2_OK || block == nullptr) {
- cout << "C2LinearBlock::map() failed : " << status << endl;
+ std::cout << "C2LinearBlock::map() failed : " << status << std::endl;
return status;
}
C2WriteView view = block->map().get();
if (view.error() != C2_OK) {
- cout << "C2LinearBlock::map() failed : " << view.error() << endl;
+ std::cout << "C2LinearBlock::map() failed : " << view.error() << std::endl;
return view.error();
}
memcpy(view.base(), inputBuffer + mOffset, size);
diff --git a/media/tests/benchmark/src/native/decoder/C2Decoder.h b/media/tests/benchmark/src/native/decoder/C2Decoder.h
index 0e79d51..4a3eb96 100644
--- a/media/tests/benchmark/src/native/decoder/C2Decoder.h
+++ b/media/tests/benchmark/src/native/decoder/C2Decoder.h
@@ -17,10 +17,6 @@
#ifndef __C2_DECODER_H__
#define __C2_DECODER_H__
-#include <stdio.h>
-#include <algorithm>
-#include <fstream>
-
#include "BenchmarkC2Common.h"
#define ALIGN(_sz, _align) (((_sz) + ((_align) - 1)) & ~((_align) - 1))
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.cpp b/media/tests/benchmark/src/native/decoder/Decoder.cpp
index ef84537..ac0d525 100644
--- a/media/tests/benchmark/src/native/decoder/Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/Decoder.cpp
@@ -32,8 +32,8 @@
int64_t timestamp = frameInfo[frameID].presentationTimeUs;
ssize_t bytesCount = frameInfo[frameID].size;
if (bufSize < bytesCount) {
- ALOGE("Error : insufficient resource");
- return make_tuple(0, AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE, 0);
+ ALOGE("Error : Buffer size is insufficient to read sample");
+ return make_tuple(0, AMEDIA_ERROR_MALFORMED, 0);
}
memcpy(buf, inputBuffer + offset, bytesCount);
@@ -54,6 +54,7 @@
size_t bufSize;
uint8_t *buf = AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
if (!buf) {
+ mErrorCode = AMEDIA_ERROR_IO;
mSignalledError = true;
mDecoderDoneCondition.notify_one();
return;
@@ -64,7 +65,8 @@
int64_t presentationTimeUs = 0;
tie(bytesRead, flag, presentationTimeUs) = readSampleData(
mInputBuffer, mOffset, mFrameMetaData, buf, mNumInputFrame, bufSize);
- if (flag == AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE) {
+ if (flag == AMEDIA_ERROR_MALFORMED) {
+ mErrorCode = (media_status_t)flag;
mSignalledError = true;
mDecoderDoneCondition.notify_one();
return;
@@ -74,9 +76,10 @@
ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRId64 " mSawInputEOS : %s", __FUNCTION__,
bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
- int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
- presentationTimeUs, flag);
+ media_status_t status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */,
+ bytesRead, presentationTimeUs, flag);
if (AMEDIA_OK != status) {
+ mErrorCode = status;
mSignalledError = true;
mDecoderDoneCondition.notify_one();
return;
@@ -127,6 +130,16 @@
}
}
+void Decoder::onError(AMediaCodec *mediaCodec, media_status_t err) {
+ ALOGV("In %s", __func__);
+ if (mediaCodec == mCodec && mediaCodec) {
+ ALOGE("Received Error %d", err);
+ mErrorCode = err;
+ mSignalledError = true;
+ mDecoderDoneCondition.notify_one();
+ }
+}
+
void Decoder::setupDecoder() {
if (!mFormat) mFormat = mExtractor->getFormat();
}
@@ -168,7 +181,8 @@
ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
- return AMEDIA_ERROR_IO;
+ mErrorCode = (media_status_t)inIdx;
+ return mErrorCode;
} else if (inIdx >= 0) {
mStats->addInputTime();
onInputAvailable(mCodec, inIdx);
@@ -188,13 +202,18 @@
} else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
- return AMEDIA_ERROR_IO;
+ mErrorCode = (media_status_t)outIdx;
+ return mErrorCode;
}
}
} else {
unique_lock<mutex> lock(mMutex);
mDecoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
}
+ if (mSignalledError) {
+ ALOGE("Received Error while Decoding");
+ return mErrorCode;
+ }
if (codecName.empty()) {
char *decName;
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.h b/media/tests/benchmark/src/native/decoder/Decoder.h
index 7630e7b..aeda080 100644
--- a/media/tests/benchmark/src/native/decoder/Decoder.h
+++ b/media/tests/benchmark/src/native/decoder/Decoder.h
@@ -38,6 +38,7 @@
mSawInputEOS(false),
mSawOutputEOS(false),
mSignalledError(false),
+ mErrorCode(AMEDIA_OK),
mInputBuffer(nullptr),
mOutFp(nullptr) {
mExtractor = new Extractor();
@@ -61,6 +62,8 @@
void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
+ void onError(AMediaCodec *mediaCodec, media_status_t err) override;
+
void onOutputAvailable(AMediaCodec *codec, int32_t index,
AMediaCodecBufferInfo *bufferInfo) override;
@@ -82,6 +85,7 @@
bool mSawInputEOS;
bool mSawOutputEOS;
bool mSignalledError;
+ media_status_t mErrorCode;
int32_t mOffset;
uint8_t *mInputBuffer;
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
index 5fdf9e3..a5605de 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -34,6 +34,7 @@
size_t bufSize = 0;
char *buf = (char *)AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
if (!buf) {
+ mErrorCode = AMEDIA_ERROR_IO;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -41,6 +42,7 @@
if (mInputBufferSize < mOffset) {
ALOGE("Out of bound access of input buffer\n");
+ mErrorCode = AMEDIA_ERROR_MALFORMED;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -51,6 +53,7 @@
}
if (bufSize < bytesRead) {
ALOGE("bytes to read %zu bufSize %zu \n", bytesRead, bufSize);
+ mErrorCode = AMEDIA_ERROR_MALFORMED;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -58,6 +61,7 @@
if (bytesRead < mParams.frameSize && mNumInputFrame < mParams.numFrames - 1) {
ALOGE("Partial frame at frameID %d bytesRead %zu frameSize %d total numFrames %d\n",
mNumInputFrame, bytesRead, mParams.frameSize, mParams.numFrames);
+ mErrorCode = AMEDIA_ERROR_MALFORMED;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -66,6 +70,7 @@
size_t bytesgcount = mEleStream->gcount();
if (bytesgcount != bytesRead) {
ALOGE("bytes to read %zu actual bytes read %zu \n", bytesRead, bytesgcount);
+ mErrorCode = AMEDIA_ERROR_MALFORMED;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -89,9 +94,10 @@
ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRIu64 " mSawInputEOS : %s", __FUNCTION__,
bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
- int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
- presentationTimeUs, flag);
+ media_status_t status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */,
+ bytesRead, presentationTimeUs, flag);
if (AMEDIA_OK != status) {
+ mErrorCode = status;
mSignalledError = true;
mEncoderDoneCondition.notify_one();
return;
@@ -133,6 +139,16 @@
}
}
+void Encoder::onError(AMediaCodec *mediaCodec, media_status_t err) {
+ ALOGV("In %s", __func__);
+ if (mediaCodec == mCodec && mediaCodec) {
+ ALOGE("Received Error %d", err);
+ mErrorCode = err;
+ mSignalledError = true;
+ mEncoderDoneCondition.notify_one();
+ }
+}
+
void Encoder::setupEncoder() {
if (!mFormat) mFormat = AMediaFormat_new();
}
@@ -235,7 +251,8 @@
ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
- return AMEDIA_ERROR_IO;
+ mErrorCode = (media_status_t)inIdx;
+ return mErrorCode;
} else if (inIdx >= 0) {
mStats->addInputTime();
onInputAvailable(mCodec, inIdx);
@@ -255,13 +272,18 @@
} else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
- return AMEDIA_ERROR_IO;
+ mErrorCode = (media_status_t)outIdx;
+ return mErrorCode;
}
}
} else {
unique_lock<mutex> lock(mMutex);
mEncoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
}
+ if (mSignalledError) {
+ ALOGE("Received Error while Encoding");
+ return mErrorCode;
+ }
if (codecName.empty()) {
char *encName;
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
index 75d9941..6059c4a 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.h
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -49,7 +49,8 @@
mNumOutputFrame(0),
mSawInputEOS(false),
mSawOutputEOS(false),
- mSignalledError(false) {}
+ mSignalledError(false),
+ mErrorCode(AMEDIA_OK) {}
virtual ~Encoder() {}
@@ -65,6 +66,8 @@
void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
+ void onError(AMediaCodec *mediaCodec, media_status_t err) override;
+
void onOutputAvailable(AMediaCodec *codec, int32_t index,
AMediaCodecBufferInfo *bufferInfo) override;
@@ -83,6 +86,7 @@
bool mSawInputEOS;
bool mSawOutputEOS;
bool mSignalledError;
+ media_status_t mErrorCode;
char *mMime;
int32_t mOffset;
diff --git a/media/tests/benchmark/tests/DecoderTest.cpp b/media/tests/benchmark/tests/DecoderTest.cpp
index 242178f..fa37435 100644
--- a/media/tests/benchmark/tests/DecoderTest.cpp
+++ b/media/tests/benchmark/tests/DecoderTest.cpp
@@ -93,7 +93,7 @@
decoder->setupDecoder();
status = decoder->decode(inputBuffer, frameInfo, codecName, asyncMode);
if (status != AMEDIA_OK) {
- cout << "[ WARN ] Test Skipped. Decode returned error \n";
+ cout << "[ WARN ] Test Failed. Decode returned error " << status << endl;
free(inputBuffer);
return;
}
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
index 9f42c64..c3963f8 100644
--- a/media/tests/benchmark/tests/EncoderTest.cpp
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -143,7 +143,11 @@
string codecName = get<1>(params);
bool asyncMode = get<2>(params);
status = encoder->encode(codecName, eleStream, eleSize, asyncMode, encParams, (char *)mime);
- ASSERT_EQ(status, 0);
+ if (status != AMEDIA_OK) {
+ cout << "[ WARN ] Test Failed. Encode returned error " << status << endl;
+ free(inputBuffer);
+ return;
+ }
encoder->deInitCodec();
cout << "codec : " << codecName << endl;
string inputReference = get<0>(params);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c10adbb..b704573 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -732,9 +732,10 @@
}
Status CameraService::makeClient(const sp<CameraService>& cameraService,
- const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
- int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+ const sp<IInterface>& cameraCb, const String16& packageName,
+ const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
+ int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
+ int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
@@ -744,7 +745,7 @@
case CAMERA_DEVICE_API_VERSION_1_0:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName,
+ *client = new CameraClient(cameraService, tmp, packageName, featureId,
api1CameraId, facing, clientPid, clientUid,
getpid());
} else { // Camera2 API route
@@ -762,15 +763,15 @@
case CAMERA_DEVICE_API_VERSION_3_5:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new Camera2Client(cameraService, tmp, packageName,
+ *client = new Camera2Client(cameraService, tmp, packageName, featureId,
cameraId, api1CameraId,
facing, clientPid, clientUid,
servicePid);
} else { // Camera2 API route
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
- *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
- facing, clientPid, clientUid, servicePid);
+ *client = new CameraDeviceClient(cameraService, tmp, packageName, featureId,
+ cameraId, facing, clientPid, clientUid, servicePid);
}
break;
default:
@@ -787,7 +788,7 @@
halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
// Only support higher HAL version device opened as HAL1.0 device.
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName,
+ *client = new CameraClient(cameraService, tmp, packageName, featureId,
api1CameraId, facing, clientPid, clientUid,
servicePid);
} else {
@@ -887,7 +888,7 @@
if (!(ret = connectHelper<ICameraClient,Client>(
sp<ICameraClient>{nullptr}, id, cameraId,
static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
- internalPackageName, uid, USE_CALLING_PID,
+ internalPackageName, std::unique_ptr<String16>(), uid, USE_CALLING_PID,
API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
).isOk()) {
ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
@@ -1400,8 +1401,8 @@
String8 id = cameraIdIntToStr(api1CameraId);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
- CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
- /*shimUpdateOnly*/ false, /*out*/client);
+ CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, std::unique_ptr<String16>(),
+ clientUid, clientPid, API_1, /*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
@@ -1427,8 +1428,8 @@
Status ret = Status::ok();
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
- clientPackageName, clientUid, USE_CALLING_PID, API_1, /*shimUpdateOnly*/ false,
- /*out*/client);
+ clientPackageName, std::unique_ptr<String16>(), clientUid, USE_CALLING_PID, API_1,
+ /*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
@@ -1502,6 +1503,7 @@
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
int clientUid,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
@@ -1511,6 +1513,7 @@
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
String16 clientPackageNameAdj = clientPackageName;
+
if (hardware::IPCThreadState::self()->isServingCall()) {
std::string vendorClient =
StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
@@ -1518,7 +1521,7 @@
}
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1,
- CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj,
+ CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
@@ -1533,8 +1536,9 @@
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
- int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
+ int api1CameraId, int halVersion, const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
+ apiLevel effectiveApiLevel, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
@@ -1617,7 +1621,7 @@
}
sp<BasicClient> tmp = nullptr;
- if(!(ret = makeClient(this, cameraCb, clientPackageName,
+ if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
cameraId, api1CameraId, facing,
clientPid, clientUid, getpid(),
halVersion, deviceVersion, effectiveApiLevel,
@@ -2459,13 +2463,14 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraIdStr,
int api1CameraId, int cameraFacing,
int clientPid, uid_t clientUid,
int servicePid) :
CameraService::BasicClient(cameraService,
IInterface::asBinder(cameraClient),
- clientPackageName,
+ clientPackageName, clientFeatureId,
cameraIdStr, cameraFacing,
clientPid, clientUid,
servicePid),
@@ -2495,17 +2500,24 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& clientPackageName,
+ const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraIdStr, int cameraFacing,
int clientPid, uid_t clientUid,
int servicePid):
mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing),
- mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
+ mClientPackageName(clientPackageName),
+ mClientPid(clientPid), mClientUid(clientUid),
mServicePid(servicePid),
mDisconnected(false),
mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
mRemoteBinder(remoteCallback)
{
+ if (clientFeatureId) {
+ mClientFeatureId = std::unique_ptr<String16>(new String16(*clientFeatureId));
+ } else {
+ mClientFeatureId = std::unique_ptr<String16>();
+ }
+
if (sCameraService == nullptr) {
sCameraService = cameraService;
}
@@ -2649,8 +2661,9 @@
int32_t res;
mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
mClientPackageName, mOpsCallback);
- res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
- mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+ res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid,
+ mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId,
+ String16("start camera ") + String16(mCameraIdStr));
if (res == AppOpsManager::MODE_ERRORED) {
ALOGI("Camera %s: Access for \"%s\" has been revoked",
@@ -2692,7 +2705,7 @@
// Notify app ops that the camera is available again
if (mAppOpsManager != nullptr) {
mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName);
+ mClientPackageName, mClientFeatureId);
mOpsActive = false;
}
// This function is called when a client disconnects. This should
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 829a3ee..1f40fc3 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -134,7 +134,8 @@
virtual binder::Status connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
- const String16& clientPackageName, int32_t clientUid,
+ const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
+ int32_t clientUid,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -275,6 +276,7 @@
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraIdStr,
int cameraFacing,
int clientPid,
@@ -294,6 +296,7 @@
const String8 mCameraIdStr;
const int mCameraFacing;
String16 mClientPackageName;
+ std::unique_ptr<String16> mClientFeatureId;
pid_t mClientPid;
const uid_t mClientUid;
const pid_t mServicePid;
@@ -365,6 +368,7 @@
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraIdStr,
int api1CameraId,
int cameraFacing,
@@ -688,8 +692,8 @@
template<class CALLBACK, class CLIENT>
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, int halVersion, const String16& clientPackageName,
- int clientUid, int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
- /*out*/sp<CLIENT>& device);
+ const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
+ apiLevel effectiveApiLevel, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
// Lock guarding camera service state
Mutex mServiceLock;
@@ -985,9 +989,10 @@
static String8 getFormattedCurrentTime();
static binder::Status makeClient(const sp<CameraService>& cameraService,
- const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
- int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+ const sp<IInterface>& cameraCb, const String16& packageName,
+ const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
+ int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
+ int deviceVersion, apiLevel effectiveApiLevel,
/*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 c273881..5dbbc0b 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -50,13 +50,14 @@
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraDeviceId,
int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
- Camera2ClientBase(cameraService, cameraClient, clientPackageName,
+ Camera2ClientBase(cameraService, cameraClient, clientPackageName, clientFeatureId,
cameraDeviceId, api1CameraId, cameraFacing,
clientPid, clientUid, servicePid),
mParameters(api1CameraId, cameraFacing)
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 8a17b17..8034ab4 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -93,6 +93,7 @@
Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraDeviceId,
int api1CameraId,
int cameraFacing,
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 388a5dc..83da880 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -34,11 +34,11 @@
CameraClient::CameraClient(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
- const String16& clientPackageName,
+ const String16& clientPackageName, const std::unique_ptr<String16>& clientFeatureId,
int cameraId, int cameraFacing,
int clientPid, int clientUid,
int servicePid):
- Client(cameraService, cameraClient, clientPackageName,
+ Client(cameraService, cameraClient, clientPackageName, clientFeatureId,
String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
clientUid, servicePid)
{
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index b26b612..501ad18 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -66,6 +66,7 @@
CameraClient(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
int cameraId,
int cameraFacing,
int clientPid,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 08fb153..27bebde 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -54,6 +54,7 @@
const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
int cameraFacing,
@@ -63,6 +64,7 @@
BasicClient(cameraService,
IInterface::asBinder(remoteCallback),
clientPackageName,
+ clientFeatureId,
cameraId,
cameraFacing,
clientPid,
@@ -78,12 +80,13 @@
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
- Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
+ Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
cameraId, /*API1 camera ID*/ -1,
cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index fe25010..7efc5ab 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -47,6 +47,7 @@
CameraDeviceClientBase(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
int cameraFacing,
@@ -163,6 +164,7 @@
CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int cameraFacing,
int clientPid,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 78feb3e..8792f9a 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -44,13 +44,14 @@
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
- TClientBase(cameraService, remoteCallback, clientPackageName,
+ TClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 6693847..12cba0b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -48,6 +48,7 @@
Camera2ClientBase(const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
+ const std::unique_ptr<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
int cameraFacing,
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 80df7db..5c6c518 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -139,7 +139,9 @@
mOutputSlots.clear();
mConsumerBufferCount.clear();
- mConsumer->consumerDisconnect();
+ if (mConsumer.get() != nullptr) {
+ mConsumer->consumerDisconnect();
+ }
if (mBuffers.size() > 0) {
SP_LOGW("%zu buffers still being tracked", mBuffers.size());
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 1daa035..97ba9c4 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -103,7 +103,7 @@
}
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
binder::Status serviceRet = mAidlICameraService->connectDevice(
- callbacks, String16(cameraId.c_str()), String16(""),
+ callbacks, String16(cameraId.c_str()), String16(""), std::unique_ptr<String16>(),
hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
diff --git a/services/mediaanalytics/TEST_MAPPING b/services/mediaanalytics/TEST_MAPPING
new file mode 100644
index 0000000..01e9e46
--- /dev/null
+++ b/services/mediaanalytics/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+ "presubmit": [
+ {
+ "name": "mediametrics_tests"
+ },
+ {
+ "name": "CtsNativeMediaMetricsTestCases"
+ }
+ ]
+}
diff --git a/services/mediaanalytics/tests/Android.bp b/services/mediaanalytics/tests/Android.bp
index 7bca1c4..a8a330c 100644
--- a/services/mediaanalytics/tests/Android.bp
+++ b/services/mediaanalytics/tests/Android.bp
@@ -1,5 +1,6 @@
cc_test {
name: "mediametrics_tests",
+ test_suites: ["device-tests"],
cflags: [
"-Wall",
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
index fa5bc4a..ad03e68 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/services/mediacodec/registrant/Android.bp
@@ -9,12 +9,11 @@
"libmedia_headers",
],
+ defaults: [
+ "libcodec2-hidl-defaults",
+ ],
shared_libs: [
- "android.hardware.media.c2@1.0",
"libbase",
- "libcodec2_hidl@1.0",
- "libcodec2_vndk",
- "libutils",
],
// Codecs
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
index 706ebee..58db801e 100644
--- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -20,11 +20,11 @@
#include <android-base/logging.h>
#include <C2PlatformSupport.h>
-#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.1/ComponentStore.h>
#include <media/CodecServiceRegistrant.h>
extern "C" void RegisterCodecServices() {
- using namespace ::android::hardware::media::c2::V1_0;
+ using namespace ::android::hardware::media::c2::V1_1;
LOG(INFO) << "Creating software Codec2 service...";
android::sp<IComponentStore> store =
new utils::ComponentStore(