1 #include "SemanticManager.h"
2
3 #include <android-base/logging.h>
4
5 #include <cstdlib>
6 #include <thread>
7
8 #include "InputFrame.h"
9 #include "types/Status.h"
10
11 namespace android {
12 namespace automotive {
13 namespace computepipe {
14 namespace runner {
15 namespace stream_manager {
16
getType() const17 proto::PacketType SemanticHandle::getType() const {
18 return mType;
19 }
20
getTimeStamp() const21 uint64_t SemanticHandle::getTimeStamp() const {
22 return mTimestamp;
23 }
24
getSize() const25 uint32_t SemanticHandle::getSize() const {
26 return mSize;
27 }
28
getData() const29 const char* SemanticHandle::getData() const {
30 return mData;
31 }
32
getHardwareBuffer() const33 AHardwareBuffer* SemanticHandle::getHardwareBuffer() const {
34 return nullptr;
35 }
36
getStreamId() const37 int SemanticHandle::getStreamId() const {
38 return mStreamId;
39 }
40
41 // Buffer id is not tracked for semantic handle as they do not need a
42 // doneWithPacket() call.
getBufferId() const43 int SemanticHandle::getBufferId() const {
44 return -1;
45 }
46
setMemInfo(int streamId,const char * data,uint32_t size,uint64_t timestamp,const proto::PacketType & type)47 Status SemanticHandle::setMemInfo(int streamId, const char* data, uint32_t size, uint64_t timestamp,
48 const proto::PacketType& type) {
49 if (data == nullptr || size == 0 || size > kMaxSemanticDataSize) {
50 return INVALID_ARGUMENT;
51 }
52 mStreamId = streamId;
53 mData = (char*)malloc(size);
54 if (!mData) {
55 return NO_MEMORY;
56 }
57 memcpy(mData, data, size);
58 mType = type;
59 mTimestamp = timestamp;
60 mSize = size;
61 return SUCCESS;
62 }
63
64 /* Destroy local copy */
~SemanticHandle()65 SemanticHandle::~SemanticHandle() {
66 free(mData);
67 }
68
setEngineInterface(std::shared_ptr<StreamEngineInterface> engine)69 void SemanticManager::setEngineInterface(std::shared_ptr<StreamEngineInterface> engine) {
70 mEngine = engine;
71 std::lock_guard<std::mutex> lock(mStateLock);
72 mState = RESET;
73 }
74
notifyEndOfStream()75 void SemanticManager::notifyEndOfStream() {
76 mEngine->notifyEndOfStream();
77 }
78
79 // TODO: b/146495240 Add support for batching
setMaxInFlightPackets(uint32_t)80 Status SemanticManager::setMaxInFlightPackets(uint32_t /* maxPackets */) {
81 if (!mEngine) {
82 return ILLEGAL_STATE;
83 }
84 mState = CONFIG_DONE;
85 return SUCCESS;
86 }
87
handleExecutionPhase(const RunnerEvent & e)88 Status SemanticManager::handleExecutionPhase(const RunnerEvent& e) {
89 std::lock_guard<std::mutex> lock(mStateLock);
90 if (mState == CONFIG_DONE && e.isPhaseEntry()) {
91 mState = RUNNING;
92 return SUCCESS;
93 }
94 if (mState == RESET) {
95 /* Cannot get to running phase from reset state without config phase*/
96 return ILLEGAL_STATE;
97 }
98 if (mState == RUNNING && e.isAborted()) {
99 /* Transition back to config completed */
100 mState = CONFIG_DONE;
101 return SUCCESS;
102 }
103 if (mState == RUNNING) {
104 return ILLEGAL_STATE;
105 }
106 return SUCCESS;
107 }
108
handleStopWithFlushPhase(const RunnerEvent & e)109 Status SemanticManager::handleStopWithFlushPhase(const RunnerEvent& e) {
110 std::lock_guard<std::mutex> lock(mStateLock);
111 if (mState == CONFIG_DONE || mState == RESET) {
112 return ILLEGAL_STATE;
113 }
114 /* Cannot have stop completed if we never entered stop state */
115 if (mState == RUNNING && (e.isAborted() || e.isTransitionComplete())) {
116 return ILLEGAL_STATE;
117 }
118 /* We are being asked to stop */
119 if (mState == RUNNING && e.isPhaseEntry()) {
120 mState = STOPPED;
121 std::thread t(&SemanticManager::notifyEndOfStream, this);
122 t.detach();
123 return SUCCESS;
124 }
125 /* Other Components have stopped, we can transition back to CONFIG_DONE */
126 if (mState == STOPPED && e.isTransitionComplete()) {
127 mState = CONFIG_DONE;
128 return SUCCESS;
129 }
130 /* We were stopped, but stop was aborted. */
131 if (mState == STOPPED && e.isAborted()) {
132 mState = RUNNING;
133 return SUCCESS;
134 }
135 return SUCCESS;
136 }
137
handleStopImmediatePhase(const RunnerEvent & e)138 Status SemanticManager::handleStopImmediatePhase(const RunnerEvent& e) {
139 return handleStopWithFlushPhase(e);
140 }
141
freePacket(int)142 Status SemanticManager::freePacket(int /* bufferId */) {
143 return SUCCESS;
144 }
145
queuePacket(const char * data,const uint32_t size,uint64_t timestamp)146 Status SemanticManager::queuePacket(const char* data, const uint32_t size, uint64_t timestamp) {
147 std::lock_guard<std::mutex> lock(mStateLock);
148 // We drop the packet since we have received the stop notifications.
149 if (mState != RUNNING) {
150 return SUCCESS;
151 }
152 // Invalid state.
153 if (mEngine == nullptr) {
154 return INTERNAL_ERROR;
155 }
156 auto memHandle = std::make_shared<SemanticHandle>();
157 auto status = memHandle->setMemInfo(mStreamId, data, size, timestamp, mType);
158 if (status != SUCCESS) {
159 return status;
160 }
161 mEngine->dispatchPacket(memHandle);
162 return SUCCESS;
163 }
164
queuePacket(const InputFrame &,uint64_t)165 Status SemanticManager::queuePacket(const InputFrame& /*inputData*/, uint64_t /*timestamp*/) {
166 LOG(ERROR) << "Unexpected call to queue a pixel packet from a semantic stream manager.";
167 return Status::ILLEGAL_STATE;
168 }
169
clonePacket(std::shared_ptr<MemHandle> handle)170 std::shared_ptr<MemHandle> SemanticManager::clonePacket(std::shared_ptr<MemHandle> handle) {
171 return handle;
172 }
173
SemanticManager(std::string name,int streamId,const proto::PacketType & type)174 SemanticManager::SemanticManager(std::string name, int streamId, const proto::PacketType& type)
175 : StreamManager(name, type), mStreamId(streamId) {
176 }
177 } // namespace stream_manager
178 } // namespace runner
179 } // namespace computepipe
180 } // namespace automotive
181 } // namespace android
182