• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 #ifndef ANDROID_MEDIA_ECO_SESSION_H_
18 #define ANDROID_MEDIA_ECO_SESSION_H_
19 
20 #include <aidl/android/media/eco/BnECOSession.h>
21 #include <aidl/android/media/eco/IECOServiceInfoListener.h>
22 #include <aidl/android/media/eco/IECOServiceStatsProvider.h>
23 
24 #include <condition_variable>
25 #include <deque>
26 #include <list>
27 #include <memory>
28 #include <mutex>
29 #include <thread>
30 
31 #include "ECOData.h"
32 #include "ECOServiceInfoListener.h"
33 #include "ECOServiceStatsProvider.h"
34 #include "ECOUtils.h"
35 
36 namespace android {
37 namespace media {
38 namespace eco {
39 
40 using aidl::android::media::eco::BnECOSession;
41 using aidl::android::media::eco::ECOData;
42 using aidl::android::media::eco::ECODataStatus;
43 using aidl::android::media::eco::IECOServiceInfoListener;
44 using aidl::android::media::eco::IECOServiceStatsProvider;
45 using ::ndk::ScopedAStatus;
46 /**
47  * ECO Session.
48  *
49  * ECOSession is created by ECOService to manage an encoding session. Both the providers and
50  * listeners should interact with ECO session after obtain it from ECOService. For ECOService 1.0,
51  * it only supports resolution of up to 720P and only for camera recording use case. Also, it only
52  * supports encoder as the provider and camera as listener.
53  */
54 class ECOSession : public BnECOSession {
55     using ::ndk::ICInterface::dump;
56 
57 public:
58     // Only the  ECOService could create ECOSession.
59     ECOSession(int32_t width, int32_t height, bool isCameraRecording);
60 
61     virtual ~ECOSession();
62 
63     virtual ScopedAStatus addStatsProvider(
64             const std::shared_ptr<IECOServiceStatsProvider>& provider, const ECOData& statsConfig,
65             /*out*/ bool* status);
66 
67     virtual ScopedAStatus removeStatsProvider(const std::shared_ptr<IECOServiceStatsProvider>&,
68                                               bool*);
69 
70     virtual ScopedAStatus addInfoListener(const std::shared_ptr<IECOServiceInfoListener>&,
71                                           const ECOData& listenerConfig,
72                                           /*out*/ bool* status);
73 
74     virtual ScopedAStatus removeInfoListener(const std::shared_ptr<IECOServiceInfoListener>&,
75                                              bool*);
76 
77     virtual ScopedAStatus pushNewStats(const ECOData&, bool*);
78 
79     virtual ScopedAStatus getWidth(int32_t* _aidl_return);
80 
81     virtual ScopedAStatus getHeight(int32_t* _aidl_return);
82 
83     virtual ScopedAStatus getIsCameraRecording(bool*);
84 
85     virtual ScopedAStatus getNumOfListeners(int32_t*);
86 
87     virtual ScopedAStatus getNumOfProviders(int32_t*);
88 
89     // Grant permission to EcoSessionTest to run test.
90     friend class EcoSessionTest;
91 
92     // Let ECOService create the session.
93     friend class ECOService;
94 
95 protected:
96     static std::shared_ptr<ECOSession> createECOSession(int32_t width, int32_t height,
97                                                         bool isCameraRecording);
98 
99 private:
100     virtual status_t dump(int fd, const std::vector<std::string>& args);
101 
102     // Start the main thread for processing the stats and pushing info to listener.
103     static void startThread(ECOSession* session);
104 
105     void run();
106 
107     bool processStats(const ECOData& stats);
108 
109     // Lock guarding ECO session state
110     std::mutex mSessionLock;
111 
112     // Process the session stats received from provider.
113     void processSessionStats(const ECOData& stats);
114 
115     // Process the frame stats received from provider.
116     void processFrameStats(const ECOData& stats);
117 
118     // Generate the latest session info if available.
119     ECOData generateLatestSessionInfoEcoData();
120 
121     std::atomic<bool> mStopThread;
122 
123     std::mutex mStatsQueueLock;
124     std::deque<ECOData> mStatsQueue;  // GUARDED_BY(mStatsQueueLock)
125     std::condition_variable mWorkerWaitCV;
126 
127     bool mNewListenerAdded = false;
128 
129     constexpr static int32_t ENCODER_MIN_QP = 0;
130     constexpr static int32_t ENCODER_MAX_QP = 51;
131 
132     // Save the QP last reported to the listener. Init to be 0.
133     int32_t mLastReportedQp;
134 
135     typedef struct QpRange {
136         int32_t mQpBlocknessThreshold = 50;
137         int32_t mQpChangeThreshold = 50;
138     } QpCondition;
139     QpCondition mListenerQpCondition;
140 
141     std::shared_ptr<IECOServiceInfoListener> mListener;
142     std::string mListenerName;
143 
144     std::shared_ptr<IECOServiceStatsProvider> mProvider;
145     std::string mProviderName;
146 
147     // Main thread for processing the events from provider.
148     std::thread mThread;
149 
150     // Width of the encoding session in number of pixels.
151     const int32_t mWidth;
152 
153     // Height of the encoding session in number of pixels.
154     const int32_t mHeight;
155 
156     // Whether the encoding is for camera recording.
157     const bool mIsCameraRecording;
158 
159     // Ouput width of the encoding session in number of pixels, -1 means not available.
160     int32_t mOutputWidth = -1;
161 
162     // Output height of the encoding session in number of pixels. -1 means not available.
163     int32_t mOutputHeight = -1;
164 
165     // Encoder codec type of the encoding session. -1 means not available.
166     int32_t mCodecType = -1;
167 
168     // Encoder codec profile. -1 means not available.
169     int32_t mCodecProfile = -1;
170 
171     // Encoder codec level. -1 means not available.
172     int32_t mCodecLevel = -1;
173 
174     // Target bitrate in bits per second. This should be provided by the provider. -1 means not
175     // available.
176     int32_t mTargetBitrateBps = -1;
177 
178     // Actual bitrate in bits per second. This should be provided by the provider. -1 means not
179     // available.
180     int32_t mActualBitrateBps = -1;
181 
182     // Key frame interval in number of frames. -1 means not available.
183     int32_t mKeyFrameIntervalFrames = -1;
184 
185     // Frame rate in frames per second. -1 means not available.
186     float mFramerateFps;
187 
188     // Debug related flags.
189     bool mLogStats;
190     uint32_t mLogStatsEntries;  // number of stats received from the provider.
191     std::list<ECOData> mStatsDebugBuffer;
192 
193     // Pushes the ECOData to the debug buffer.
194     void logStats(const ECOData& data);
195 
196     bool mLogInfo;
197     uint32_t mLogInfoEntries;  // number of infos sent to the listener.
198     std::list<ECOData> mInfosDebugBuffer;
199 
200     // Pushes the ECOData to the debug buffer.
201     void logInfos(const ECOData& data);
202 };
203 
204 }  // namespace eco
205 }  // namespace media
206 }  // namespace android
207 
208 #endif  // ANDROID_MEDIA_ECO_SESSION_H_
209