1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include <android-base/logging.h>
15
16 #include <fcntl.h>
17 #include <chrono>
18
19 #include "VideoInputManager.h"
20
21 namespace android {
22 namespace automotive {
23 namespace computepipe {
24 namespace runner {
25 namespace input_manager {
26
VideoInputManager(const proto::InputConfig & inputConfig,const proto::InputConfig &,std::shared_ptr<InputEngineInterface> inputEngineInterface)27 VideoInputManager::VideoInputManager(const proto::InputConfig& inputConfig,
28 const proto::InputConfig& /*overrideConfig*/,
29 std::shared_ptr<InputEngineInterface> inputEngineInterface) :
30 mEngine(inputEngineInterface),
31 mInputConfig(inputConfig) {}
32
~VideoInputManager()33 VideoInputManager::~VideoInputManager() {}
34
createVideoInputManager(const proto::InputConfig & inputConfig,const proto::InputConfig & overrideConfig,std::shared_ptr<InputEngineInterface> inputEngineInterface)35 std::unique_ptr<VideoInputManager> VideoInputManager::createVideoInputManager(
36 const proto::InputConfig& inputConfig, const proto::InputConfig& overrideConfig,
37 std::shared_ptr<InputEngineInterface> inputEngineInterface) {
38 return std::make_unique<VideoInputManager>(inputConfig, overrideConfig, inputEngineInterface);
39 }
40
handleExecutionPhase(const RunnerEvent & e)41 Status VideoInputManager::handleExecutionPhase(const RunnerEvent& e) {
42 if (e.isTransitionComplete()) {
43 return Status::SUCCESS;
44 }
45
46 if (e.isPhaseEntry()) {
47 populateDecoders();
48
49 if (mVideoDecoders.empty() || mVideoDecoders.size() != mInputConfig.input_stream_size()) {
50 resetDecoders();
51 LOG(ERROR) << "Created " << mVideoDecoders.size() << " video decoders, while expecting "
52 << mInputConfig.input_stream_size() << " video decoders.";
53 return Status::INTERNAL_ERROR;
54 }
55 Status status = startDecoders();
56 if (status != Status::SUCCESS) {
57 resetDecoders();
58 }
59 return status;
60 }
61 // e.isPhaseAborted();
62 resetDecoders();
63 return Status::SUCCESS;
64 }
65
handleStopImmediatePhase(const RunnerEvent &)66 Status VideoInputManager::handleStopImmediatePhase(const RunnerEvent& /*e*/) {
67 resetDecoders();
68 return Status::SUCCESS;
69 }
70
handleStopWithFlushPhase(const RunnerEvent &)71 Status VideoInputManager::handleStopWithFlushPhase(const RunnerEvent& /*e*/) {
72 resetDecoders();
73 return Status::SUCCESS;
74 }
75
handleResetPhase(const RunnerEvent &)76 Status VideoInputManager::handleResetPhase(const RunnerEvent& /*e*/) {
77 resetDecoders();
78 return Status::SUCCESS;
79 }
80
populateDecoders()81 void VideoInputManager::populateDecoders() {
82 for (const auto& config : mInputConfig.input_stream()) {
83 if (config.has_video_config() && config.video_config().has_file_path() &&
84 !config.video_config().file_path().empty()) {
85 mVideoDecoders.emplace_back(std::make_unique<VideoDecoder>(config, mEngine));
86 }
87 }
88 }
89
startDecoders()90 Status VideoInputManager::startDecoders() {
91 if (mVideoDecoders.empty()) {
92 return Status::INTERNAL_ERROR;
93 }
94
95 float decoder0Rate = mVideoDecoders[0]->getPlaybackFrameRate();
96 for (int i = 1; i < mVideoDecoders.size(); i++) {
97 float currentDecoderRate = mVideoDecoders[i]->getPlaybackFrameRate();
98 if (std::fabs(decoder0Rate - currentDecoderRate) > std::numeric_limits<float>::epsilon()) {
99 LOG(ERROR) << "Different playback frame rate between streams (0, " << i
100 << "), frame rates - " << decoder0Rate << ", " << currentDecoderRate;
101 return Status::INTERNAL_ERROR;
102 }
103 }
104 auto timePoint = std::chrono::system_clock::now();
105 int64_t timestamp = std::chrono::time_point_cast<std::chrono::microseconds>(timePoint)
106 .time_since_epoch()
107 .count();
108 LOG(ERROR) << "Initial time is " << timestamp;
109 for (int i = 0; i < mVideoDecoders.size(); i++) {
110 mVideoDecoders[i]->setInitialTimestamp(timestamp);
111 Status status = mVideoDecoders[i]->startDecoding();
112 if (status != Status::SUCCESS) {
113 return status;
114 }
115 }
116 return Status::SUCCESS;
117 }
118
resetDecoders()119 void VideoInputManager::resetDecoders() {
120 for (int i = 0; i < mVideoDecoders.size(); i++) {
121 mVideoDecoders[i]->stopDecoding();
122 }
123 mVideoDecoders.clear();
124 }
125
126 } // namespace input_manager
127 } // namespace runner
128 } // namespace computepipe
129 } // namespace automotive
130 } // namespace android
131