• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 C_CODEC_H_
18 #define C_CODEC_H_
19 
20 #include <chrono>
21 #include <list>
22 #include <memory>
23 #include <set>
24 
25 #include <C2Component.h>
26 #include <codec2/hidl/client.h>
27 
28 #include <android/native_window.h>
29 #include <media/hardware/MetadataBufferType.h>
30 #include <media/stagefright/foundation/Mutexed.h>
31 #include <media/stagefright/CodecBase.h>
32 #include <media/stagefright/FrameRenderTracker.h>
33 #include <media/stagefright/MediaDefs.h>
34 #include <media/stagefright/SkipCutBuffer.h>
35 #include <utils/NativeHandle.h>
36 #include <hardware/gralloc.h>
37 #include <nativebase/nativebase.h>
38 
39 #include "CCodecConfig.h"
40 
41 namespace android {
42 
43 class CCodecBufferChannel;
44 class InputSurfaceWrapper;
45 struct MediaCodecInfo;
46 
47 class CCodec : public CodecBase {
48 public:
49     CCodec();
50 
51     virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
52     virtual void initiateAllocateComponent(const sp<AMessage> &msg) override;
53     virtual void initiateConfigureComponent(const sp<AMessage> &msg) override;
54     virtual void initiateCreateInputSurface() override;
55     virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override;
56     virtual void initiateStart() override;
57     virtual void initiateShutdown(bool keepComponentAllocated = false) override;
58 
59     virtual status_t setSurface(const sp<Surface> &surface) override;
60 
61     virtual void signalFlush() override;
62     virtual void signalResume() override;
63 
64     virtual void signalSetParameters(const sp<AMessage> &params) override;
65     virtual void signalEndOfInputStream() override;
66     virtual void signalRequestIDRFrame() override;
67 
68     void initiateReleaseIfStuck();
69     void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems,
70                     size_t numDiscardedInputBuffers);
71     void onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer);
72 
73 protected:
74     virtual ~CCodec();
75 
76     virtual void onMessageReceived(const sp<AMessage> &msg) override;
77 
78 private:
79     typedef std::chrono::time_point<std::chrono::steady_clock> TimePoint;
80 
81     status_t tryAndReportOnError(std::function<status_t()> job);
82 
83     void initiateStop();
84     void initiateRelease(bool sendCallback = true);
85 
86     void allocate(const sp<MediaCodecInfo> &codecInfo);
87     void configure(const sp<AMessage> &msg);
88     void start();
89     void stop();
90     void flush();
91     void release(bool sendCallback);
92 
93     void createInputSurface();
94     void setInputSurface(const sp<PersistentSurface> &surface);
95     status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
96     void setParameters(const sp<AMessage> &params);
97 
98     void setDeadline(
99             const TimePoint &now,
100             const std::chrono::milliseconds &timeout,
101             const char *name);
102 
103     void onWorkQueued(bool eos);
104     void subQueuedWorkCount(uint32_t count);
105 
106     enum {
107         kWhatAllocate,
108         kWhatConfigure,
109         kWhatStart,
110         kWhatFlush,
111         kWhatStop,
112         kWhatRelease,
113         kWhatCreateInputSurface,
114         kWhatSetInputSurface,
115         kWhatSetParameters,
116 
117         kWhatWorkDone,
118         kWhatWatch,
119     };
120 
121     enum {
122         RELEASED,
123         ALLOCATED,
124         FLUSHED,
125         RUNNING,
126 
127         ALLOCATING,  // RELEASED -> ALLOCATED
128         STARTING,    // ALLOCATED -> RUNNING
129         STOPPING,    // RUNNING -> ALLOCATED
130         FLUSHING,    // RUNNING -> FLUSHED
131         RESUMING,    // FLUSHED -> RUNNING
132         RELEASING,   // {ANY EXCEPT RELEASED} -> RELEASED
133     };
134 
135     struct State {
StateState136         inline State() : mState(RELEASED) {}
getState137         inline int get() const { return mState; }
setState138         inline void set(int newState) { mState = newState; }
139 
140         std::shared_ptr<Codec2Client::Component> comp;
141     private:
142         int mState;
143     };
144 
145     struct NamedTimePoint {
NamedTimePointNamedTimePoint146         NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
147 
setNamedTimePoint148         inline void set(
149                 const TimePoint &timePoint,
150                 const char *name) {
151             mTimePoint = timePoint;
152             mName = name;
153         }
154 
getNamedTimePoint155         inline TimePoint get() const { return mTimePoint; }
getNameNamedTimePoint156         inline const char *getName() const { return mName; }
157     private:
158         TimePoint mTimePoint;
159         const char *mName;
160     };
161 
162     Mutexed<State> mState;
163     std::shared_ptr<CCodecBufferChannel> mChannel;
164 
165     std::shared_ptr<Codec2Client> mClient;
166     std::shared_ptr<Codec2Client::Listener> mClientListener;
167     struct ClientListener;
168 
169     Mutexed<NamedTimePoint> mDeadline;
170     std::atomic_int32_t mQueuedWorkCount;
171     Mutexed<NamedTimePoint> mQueueDeadline;
172     Mutexed<NamedTimePoint> mEosDeadline;
173     typedef CCodecConfig Config;
174     Mutexed<Config> mConfig;
175     Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
176     Mutexed<std::list<size_t>> mNumDiscardedInputBuffersQueue;
177 
178     friend class CCodecCallbackImpl;
179 
180     DISALLOW_EVIL_CONSTRUCTORS(CCodec);
181 };
182 
183 }  // namespace android
184 
185 #endif  // C_CODEC_H_
186