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 #include "CCodecConfig.h" 41 42 namespace android { 43 44 class CCodecBufferChannel; 45 class InputSurfaceWrapper; 46 struct MediaCodecInfo; 47 48 class CCodec : public CodecBase { 49 public: 50 CCodec(); 51 52 virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override; 53 virtual void initiateAllocateComponent(const sp<AMessage> &msg) override; 54 virtual void initiateConfigureComponent(const sp<AMessage> &msg) override; 55 virtual void initiateCreateInputSurface() override; 56 virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override; 57 virtual void initiateStart() override; 58 virtual void initiateShutdown(bool keepComponentAllocated = false) override; 59 60 virtual status_t setSurface(const sp<Surface> &surface) override; 61 62 virtual void signalFlush() override; 63 virtual void signalResume() override; 64 65 virtual void signalSetParameters(const sp<AMessage> ¶ms) override; 66 virtual void signalEndOfInputStream() override; 67 virtual void signalRequestIDRFrame() override; 68 69 void initiateReleaseIfStuck(); 70 void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems); 71 void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex); 72 73 protected: 74 virtual ~CCodec(); 75 76 virtual void onMessageReceived(const sp<AMessage> &msg) override; 77 78 private: 79 typedef std::chrono::steady_clock::time_point 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 /** 94 * Creates an input surface for the current device configuration compatible with CCodec. 95 * This could be backed by the C2 HAL or the OMX HAL. 96 */ 97 static sp<PersistentSurface> CreateCompatibleInputSurface(); 98 99 /// Creates an input surface to the OMX HAL 100 static sp<PersistentSurface> CreateOmxInputSurface(); 101 102 /// handle a create input surface call 103 void createInputSurface(); 104 void setInputSurface(const sp<PersistentSurface> &surface); 105 status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface); 106 107 void setDeadline( 108 const TimePoint &now, 109 const std::chrono::milliseconds &timeout, 110 const char *name); 111 112 enum { 113 kWhatAllocate, 114 kWhatConfigure, 115 kWhatStart, 116 kWhatFlush, 117 kWhatStop, 118 kWhatRelease, 119 kWhatCreateInputSurface, 120 kWhatSetInputSurface, 121 kWhatSetParameters, 122 123 kWhatWorkDone, 124 kWhatWatch, 125 }; 126 127 enum { 128 RELEASED, 129 ALLOCATED, 130 FLUSHED, 131 RUNNING, 132 133 ALLOCATING, // RELEASED -> ALLOCATED 134 STARTING, // ALLOCATED -> RUNNING 135 STOPPING, // RUNNING -> ALLOCATED 136 FLUSHING, // RUNNING -> FLUSHED 137 RESUMING, // FLUSHED -> RUNNING 138 RELEASING, // {ANY EXCEPT RELEASED} -> RELEASED 139 }; 140 141 struct State { StateState142 inline State() : mState(RELEASED) {} getState143 inline int get() const { return mState; } setState144 inline void set(int newState) { mState = newState; } 145 146 std::shared_ptr<Codec2Client::Component> comp; 147 private: 148 int mState; 149 }; 150 151 struct NamedTimePoint { NamedTimePointNamedTimePoint152 NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {} 153 setNamedTimePoint154 inline void set( 155 const TimePoint &timePoint, 156 const char *name) { 157 mTimePoint = timePoint; 158 mName = name; 159 } 160 getNamedTimePoint161 inline TimePoint get() const { return mTimePoint; } getNameNamedTimePoint162 inline const char *getName() const { return mName; } 163 private: 164 TimePoint mTimePoint; 165 const char *mName; 166 }; 167 168 Mutexed<State> mState; 169 std::shared_ptr<CCodecBufferChannel> mChannel; 170 171 std::shared_ptr<Codec2Client> mClient; 172 std::shared_ptr<Codec2Client::Listener> mClientListener; 173 struct ClientListener; 174 175 Mutexed<NamedTimePoint> mDeadline; 176 typedef CCodecConfig Config; 177 Mutexed<Config> mConfig; 178 Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue; 179 std::atomic_flag mSentConfigAfterResume; 180 181 friend class CCodecCallbackImpl; 182 183 DISALLOW_EVIL_CONSTRUCTORS(CCodec); 184 }; 185 186 } // namespace android 187 188 #endif // C_CODEC_H_ 189