/* * 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); protected: virtual ~CCodec(); virtual void onMessageReceived(const sp<AMessage> &msg) override; private: typedef std::chrono::time_point<std::chrono::steady_clock> 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); void createInputSurface(); void setInputSurface(const sp<PersistentSurface> &surface); status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface); void setParameters(const sp<AMessage> ¶ms); void setDeadline(const TimePoint &deadline, const char *name); enum { kWhatAllocate, kWhatConfigure, kWhatStart, kWhatFlush, kWhatStop, kWhatRelease, kWhatCreateInputSurface, kWhatSetInputSurface, kWhatSetParameters, kWhatWorkDone, }; 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_