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