1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "HidlCameraStream.h"
18
19 #include "HidlCamera.h"
20 #include "utils/include/Utils.h"
21
22 #include <aidlcommonsupport/NativeHandle.h>
23 #include <android-base/logging.h>
24 #include <utils/SystemClock.h>
25
26 namespace aidl::android::automotive::evs::implementation {
27
28 namespace hidlevs = ::android::hardware::automotive::evs;
29
30 using ::aidl::android::hardware::automotive::evs::BufferDesc;
31 using ::aidl::android::hardware::automotive::evs::EvsEventDesc;
32 using ::aidl::android::hardware::automotive::evs::EvsEventType;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::Return;
35 using ::android::hardware::Status;
36 using ::ndk::ScopedAStatus;
37
deliverFrame(const hidlevs::V1_0::BufferDesc & buffer)38 Return<void> HidlCameraStream::deliverFrame(const hidlevs::V1_0::BufferDesc& buffer) {
39 if (!mAidlStream) {
40 LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
41 return {};
42 }
43
44 std::vector<BufferDesc> aidlBuffers(1);
45 aidlBuffers[0] = std::move(Utils::makeFromHidl(buffer, /* doDup= */ true));
46
47 if (::android::isAidlNativeHandleEmpty(aidlBuffers[0].buffer.handle)) {
48 LOG(DEBUG) << "Received a null buffer, which is the mark of the end of the stream.";
49 EvsEventDesc event{
50 .aType = EvsEventType::STREAM_STOPPED,
51 };
52 if (!mAidlStream->notify(event).isOk()) {
53 LOG(ERROR) << "Error delivering the end of stream marker";
54 }
55 }
56
57 // android::hardware::automotive::evs::V1_0::BufferDesc does not contain a
58 // timestamp so we need to fill it here.
59 aidlBuffers[0].timestamp = static_cast<int64_t>(::android::elapsedRealtimeNano() * 1e+3);
60 aidlBuffers[0].deviceId = mSourceDeviceId;
61
62 mHidlV0Buffers.push_back(buffer);
63 auto aidlStatus = mAidlStream->deliverFrame(std::move(aidlBuffers));
64 if (!aidlStatus.isOk()) {
65 LOG(ERROR) << "Failed to forward frames to AIDL client";
66 }
67
68 return {};
69 }
70
deliverFrame_1_1(const hidl_vec<hidlevs::V1_1::BufferDesc> & buffers)71 Return<void> HidlCameraStream::deliverFrame_1_1(
72 const hidl_vec<hidlevs::V1_1::BufferDesc>& buffers) {
73 if (!mAidlStream) {
74 LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
75 return {};
76 }
77
78 std::vector<BufferDesc> aidlBuffers(buffers.size());
79 for (auto i = 0; i < buffers.size(); ++i) {
80 hidlevs::V1_1::BufferDesc buffer = std::move(buffers[i]);
81 aidlBuffers[i] = std::move(Utils::makeFromHidl(buffer, /* doDup= */ true));
82 mHidlV1Buffers.push_back(std::move(buffer));
83 }
84
85 if (!mAidlStream->deliverFrame(std::move(aidlBuffers)).isOk()) {
86 LOG(ERROR) << "Failed to forward frames to AIDL client";
87 }
88
89 return {};
90 }
91
notify(const hidlevs::V1_1::EvsEventDesc & event)92 Return<void> HidlCameraStream::notify(const hidlevs::V1_1::EvsEventDesc& event) {
93 if (!mAidlStream) {
94 LOG(ERROR) << "A reference to AIDL IEvsCameraStream is invalid.";
95 return {};
96 }
97
98 if (!mAidlStream->notify(std::move(Utils::makeFromHidl(event))).isOk()) {
99 LOG(ERROR) << "Failed to forward events to AIDL client";
100 }
101
102 return {};
103 }
104
getHidlBuffer(int id,hidlevs::V1_0::BufferDesc * _return)105 bool HidlCameraStream::getHidlBuffer(int id, hidlevs::V1_0::BufferDesc* _return) {
106 auto it = std::find_if(mHidlV0Buffers.begin(), mHidlV0Buffers.end(),
107 [id](const hidlevs::V1_0::BufferDesc& buffer) {
108 return id == buffer.bufferId;
109 });
110 if (it == mHidlV0Buffers.end()) {
111 return false;
112 }
113
114 *_return = std::move(*it);
115 mHidlV0Buffers.erase(it);
116 return true;
117 }
118
getHidlBuffer(int id,hidlevs::V1_1::BufferDesc * _return)119 bool HidlCameraStream::getHidlBuffer(int id, hidlevs::V1_1::BufferDesc* _return) {
120 auto it = std::find_if(mHidlV1Buffers.begin(), mHidlV1Buffers.end(),
121 [id](const hidlevs::V1_1::BufferDesc& buffer) {
122 return id == buffer.bufferId;
123 });
124 if (it == mHidlV1Buffers.end()) {
125 return false;
126 }
127
128 *_return = std::move(*it);
129 mHidlV1Buffers.erase(it);
130 return true;
131 }
132
133 } // namespace aidl::android::automotive::evs::implementation
134