• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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