• 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 <atomic>
21 #include <chrono>
22 #include <list>
23 #include <memory>
24 #include <set>
25 
26 #include <C2Component.h>
27 #include <codec2/hidl/client.h>
28 
29 #include <android/native_window.h>
30 #include <media/hardware/MetadataBufferType.h>
31 #include <media/stagefright/foundation/Mutexed.h>
32 #include <media/stagefright/CodecBase.h>
33 #include <media/stagefright/FrameRenderTracker.h>
34 #include <media/stagefright/MediaDefs.h>
35 #include <media/stagefright/SkipCutBuffer.h>
36 #include <utils/NativeHandle.h>
37 #include <hardware/gralloc.h>
38 #include <nativebase/nativebase.h>
39 
40 namespace android {
41 
42 class CCodecBufferChannel;
43 class InputSurfaceWrapper;
44 struct CCodecConfig;
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     virtual status_t querySupportedParameters(std::vector<std::string> *names) override;
69     virtual status_t describeParameter(
70             const std::string &name, CodecParameterDescriptor *desc) override;
71     virtual status_t subscribeToParameters(const std::vector<std::string> &names) override;
72     virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names) override;
73 
74     void initiateReleaseIfStuck();
75     void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems);
76     void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex);
77 
78     static PersistentSurface *CreateInputSurface();
79 
80     static status_t CanFetchLinearBlock(
81             const std::vector<std::string> &names, const C2MemoryUsage &usage, bool *isCompatible);
82 
83     static std::shared_ptr<C2LinearBlock> FetchLinearBlock(
84             size_t capacity, const C2MemoryUsage &usage, const std::vector<std::string> &names);
85 
86     static status_t CanFetchGraphicBlock(
87             const std::vector<std::string> &names, bool *isCompatible);
88 
89     static std::shared_ptr<C2GraphicBlock> FetchGraphicBlock(
90             int32_t width,
91             int32_t height,
92             int32_t format,
93             uint64_t usage,
94             const std::vector<std::string> &names);
95 
96 protected:
97     virtual ~CCodec();
98 
99     virtual void onMessageReceived(const sp<AMessage> &msg) override;
100 
101 private:
102     typedef std::chrono::steady_clock::time_point TimePoint;
103 
104     status_t tryAndReportOnError(std::function<status_t()> job);
105 
106     void initiateStop();
107     void initiateRelease(bool sendCallback = true);
108 
109     void allocate(const sp<MediaCodecInfo> &codecInfo);
110     void configure(const sp<AMessage> &msg);
111     void start();
112     void stop();
113     void flush();
114     void release(bool sendCallback);
115 
116     /**
117      * Creates an input surface for the current device configuration compatible with CCodec.
118      * This could be backed by the C2 HAL or the OMX HAL.
119      */
120     static sp<PersistentSurface> CreateCompatibleInputSurface();
121 
122     /// Creates an input surface to the OMX HAL
123     static sp<PersistentSurface> CreateOmxInputSurface();
124 
125     /// handle a create input surface call
126     void createInputSurface();
127     void setInputSurface(const sp<PersistentSurface> &surface);
128     status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
129 
130     void setDeadline(
131             const TimePoint &now,
132             const std::chrono::milliseconds &timeout,
133             const char *name);
134 
135     status_t configureTunneledVideoPlayback(
136             const std::shared_ptr<Codec2Client::Component> comp,
137             sp<NativeHandle> *sidebandHandle,
138             const sp<AMessage> &msg);
139 
140     enum {
141         kWhatAllocate,
142         kWhatConfigure,
143         kWhatStart,
144         kWhatFlush,
145         kWhatStop,
146         kWhatRelease,
147         kWhatCreateInputSurface,
148         kWhatSetInputSurface,
149         kWhatSetParameters,
150 
151         kWhatWorkDone,
152         kWhatWatch,
153     };
154 
155     enum {
156         RELEASED,
157         ALLOCATED,
158         FLUSHED,
159         RUNNING,
160 
161         ALLOCATING,  // RELEASED -> ALLOCATED
162         STARTING,    // ALLOCATED -> RUNNING
163         STOPPING,    // RUNNING -> ALLOCATED
164         FLUSHING,    // RUNNING -> FLUSHED
165         RESUMING,    // FLUSHED -> RUNNING
166         RELEASING,   // {ANY EXCEPT RELEASED} -> RELEASED
167     };
168 
169     struct State {
StateState170         inline State() : mState(RELEASED) {}
getState171         inline int get() const { return mState; }
setState172         inline void set(int newState) { mState = newState; }
173 
174         std::shared_ptr<Codec2Client::Component> comp;
175     private:
176         int mState;
177     };
178 
179     struct NamedTimePoint {
NamedTimePointNamedTimePoint180         NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
181 
setNamedTimePoint182         inline void set(
183                 const TimePoint &timePoint,
184                 const char *name) {
185             mTimePoint = timePoint;
186             mName = name;
187         }
188 
getNamedTimePoint189         inline TimePoint get() const { return mTimePoint; }
getNameNamedTimePoint190         inline const char *getName() const { return mName; }
191     private:
192         TimePoint mTimePoint;
193         const char *mName;
194     };
195 
196     Mutexed<State> mState;
197     std::shared_ptr<CCodecBufferChannel> mChannel;
198 
199     std::shared_ptr<Codec2Client> mClient;
200     std::shared_ptr<Codec2Client::Listener> mClientListener;
201     struct ClientListener;
202 
203     Mutexed<NamedTimePoint> mDeadline;
204 
205     Mutexed<std::unique_ptr<CCodecConfig>> mConfig;
206     Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
207 
208     friend class CCodecCallbackImpl;
209 
210     DISALLOW_EVIL_CONSTRUCTORS(CCodec);
211 };
212 
213 }  // namespace android
214 
215 #endif  // C_CODEC_H_
216