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 <chrono>
21#include <list>
22#include <memory>
23#include <set>
24
25#include <C2Component.h>
26#include <codec2/hidl/client.h>
27
28#include <android/native_window.h>
29#include <media/hardware/MetadataBufferType.h>
30#include <media/stagefright/foundation/Mutexed.h>
31#include <media/stagefright/CodecBase.h>
32#include <media/stagefright/FrameRenderTracker.h>
33#include <media/stagefright/MediaDefs.h>
34#include <media/stagefright/SkipCutBuffer.h>
35#include <utils/NativeHandle.h>
36#include <hardware/gralloc.h>
37#include <nativebase/nativebase.h>
38
39#include "CCodecConfig.h"
40
41namespace android {
42
43class CCodecBufferChannel;
44class InputSurfaceWrapper;
45struct MediaCodecInfo;
46
47class CCodec : public CodecBase {
48public:
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    void initiateReleaseIfStuck();
69    void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems);
70
71protected:
72    virtual ~CCodec();
73
74    virtual void onMessageReceived(const sp<AMessage> &msg) override;
75
76private:
77    typedef std::chrono::time_point<std::chrono::steady_clock> TimePoint;
78
79    status_t tryAndReportOnError(std::function<status_t()> job);
80
81    void initiateStop();
82    void initiateRelease(bool sendCallback = true);
83
84    void allocate(const sp<MediaCodecInfo> &codecInfo);
85    void configure(const sp<AMessage> &msg);
86    void start();
87    void stop();
88    void flush();
89    void release(bool sendCallback);
90
91    void createInputSurface();
92    void setInputSurface(const sp<PersistentSurface> &surface);
93    status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
94    void setParameters(const sp<AMessage> &params);
95
96    void setDeadline(const TimePoint &deadline, const char *name);
97
98    enum {
99        kWhatAllocate,
100        kWhatConfigure,
101        kWhatStart,
102        kWhatFlush,
103        kWhatStop,
104        kWhatRelease,
105        kWhatCreateInputSurface,
106        kWhatSetInputSurface,
107        kWhatSetParameters,
108
109        kWhatWorkDone,
110    };
111
112    enum {
113        RELEASED,
114        ALLOCATED,
115        FLUSHED,
116        RUNNING,
117
118        ALLOCATING,  // RELEASED -> ALLOCATED
119        STARTING,    // ALLOCATED -> RUNNING
120        STOPPING,    // RUNNING -> ALLOCATED
121        FLUSHING,    // RUNNING -> FLUSHED
122        RESUMING,    // FLUSHED -> RUNNING
123        RELEASING,   // {ANY EXCEPT RELEASED} -> RELEASED
124    };
125
126    struct State {
127        inline State() : mState(RELEASED) {}
128        inline int get() const { return mState; }
129        inline void set(int newState) { mState = newState; }
130
131        std::shared_ptr<Codec2Client::Component> comp;
132    private:
133        int mState;
134    };
135
136    struct NamedTimePoint {
137        NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
138
139        inline void set(
140                const TimePoint &timePoint,
141                const char *name) {
142            mTimePoint = timePoint;
143            mName = name;
144        }
145
146        inline TimePoint get() const { return mTimePoint; }
147        inline const char *getName() const { return mName; }
148    private:
149        TimePoint mTimePoint;
150        const char *mName;
151    };
152
153    Mutexed<State> mState;
154    std::shared_ptr<CCodecBufferChannel> mChannel;
155
156    std::shared_ptr<Codec2Client> mClient;
157    std::shared_ptr<Codec2Client::Listener> mClientListener;
158    struct ClientListener;
159
160    Mutexed<NamedTimePoint> mDeadline;
161    typedef CCodecConfig Config;
162    Mutexed<Config> mConfig;
163    Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
164
165    friend class CCodecCallbackImpl;
166
167    DISALLOW_EVIL_CONSTRUCTORS(CCodec);
168};
169
170}  // namespace android
171
172#endif  // C_CODEC_H_
173