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> ¶ms) 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