| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef C_CODEC_H_ |
| #define C_CODEC_H_ |
| |
| #include <chrono> |
| #include <list> |
| #include <memory> |
| #include <set> |
| |
| #include <C2Component.h> |
| #include <codec2/hidl/client.h> |
| |
| #include <android/native_window.h> |
| #include <media/hardware/MetadataBufferType.h> |
| #include <media/stagefright/foundation/Mutexed.h> |
| #include <media/stagefright/CodecBase.h> |
| #include <media/stagefright/FrameRenderTracker.h> |
| #include <media/stagefright/MediaDefs.h> |
| #include <media/stagefright/SkipCutBuffer.h> |
| #include <utils/NativeHandle.h> |
| #include <hardware/gralloc.h> |
| #include <nativebase/nativebase.h> |
| |
| #include "CCodecConfig.h" |
| |
| namespace android { |
| |
| class CCodecBufferChannel; |
| class InputSurfaceWrapper; |
| struct MediaCodecInfo; |
| |
| class CCodec : public CodecBase { |
| public: |
| CCodec(); |
| |
| virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override; |
| virtual void initiateAllocateComponent(const sp<AMessage> &msg) override; |
| virtual void initiateConfigureComponent(const sp<AMessage> &msg) override; |
| virtual void initiateCreateInputSurface() override; |
| virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override; |
| virtual void initiateStart() override; |
| virtual void initiateShutdown(bool keepComponentAllocated = false) override; |
| |
| virtual status_t setSurface(const sp<Surface> &surface) override; |
| |
| virtual void signalFlush() override; |
| virtual void signalResume() override; |
| |
| virtual void signalSetParameters(const sp<AMessage> ¶ms) override; |
| virtual void signalEndOfInputStream() override; |
| virtual void signalRequestIDRFrame() override; |
| |
| void initiateReleaseIfStuck(); |
| void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems); |
| void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex); |
| |
| protected: |
| virtual ~CCodec(); |
| |
| virtual void onMessageReceived(const sp<AMessage> &msg) override; |
| |
| private: |
| typedef std::chrono::steady_clock::time_point TimePoint; |
| |
| status_t tryAndReportOnError(std::function<status_t()> job); |
| |
| void initiateStop(); |
| void initiateRelease(bool sendCallback = true); |
| |
| void allocate(const sp<MediaCodecInfo> &codecInfo); |
| void configure(const sp<AMessage> &msg); |
| void start(); |
| void stop(); |
| void flush(); |
| void release(bool sendCallback); |
| |
| /** |
| * Creates an input surface for the current device configuration compatible with CCodec. |
| * This could be backed by the C2 HAL or the OMX HAL. |
| */ |
| static sp<PersistentSurface> CreateCompatibleInputSurface(); |
| |
| /// Creates an input surface to the OMX HAL |
| static sp<PersistentSurface> CreateOmxInputSurface(); |
| |
| /// handle a create input surface call |
| void createInputSurface(); |
| void setInputSurface(const sp<PersistentSurface> &surface); |
| status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface); |
| |
| void setDeadline( |
| const TimePoint &now, |
| const std::chrono::milliseconds &timeout, |
| const char *name); |
| |
| enum { |
| kWhatAllocate, |
| kWhatConfigure, |
| kWhatStart, |
| kWhatFlush, |
| kWhatStop, |
| kWhatRelease, |
| kWhatCreateInputSurface, |
| kWhatSetInputSurface, |
| kWhatSetParameters, |
| |
| kWhatWorkDone, |
| kWhatWatch, |
| }; |
| |
| enum { |
| RELEASED, |
| ALLOCATED, |
| FLUSHED, |
| RUNNING, |
| |
| ALLOCATING, // RELEASED -> ALLOCATED |
| STARTING, // ALLOCATED -> RUNNING |
| STOPPING, // RUNNING -> ALLOCATED |
| FLUSHING, // RUNNING -> FLUSHED |
| RESUMING, // FLUSHED -> RUNNING |
| RELEASING, // {ANY EXCEPT RELEASED} -> RELEASED |
| }; |
| |
| struct State { |
| inline State() : mState(RELEASED) {} |
| inline int get() const { return mState; } |
| inline void set(int newState) { mState = newState; } |
| |
| std::shared_ptr<Codec2Client::Component> comp; |
| private: |
| int mState; |
| }; |
| |
| struct NamedTimePoint { |
| NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {} |
| |
| inline void set( |
| const TimePoint &timePoint, |
| const char *name) { |
| mTimePoint = timePoint; |
| mName = name; |
| } |
| |
| inline TimePoint get() const { return mTimePoint; } |
| inline const char *getName() const { return mName; } |
| private: |
| TimePoint mTimePoint; |
| const char *mName; |
| }; |
| |
| Mutexed<State> mState; |
| std::shared_ptr<CCodecBufferChannel> mChannel; |
| |
| std::shared_ptr<Codec2Client> mClient; |
| std::shared_ptr<Codec2Client::Listener> mClientListener; |
| struct ClientListener; |
| |
| Mutexed<NamedTimePoint> mDeadline; |
| typedef CCodecConfig Config; |
| Mutexed<Config> mConfig; |
| Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue; |
| |
| friend class CCodecCallbackImpl; |
| |
| DISALLOW_EVIL_CONSTRUCTORS(CCodec); |
| }; |
| |
| } // namespace android |
| |
| #endif // C_CODEC_H_ |