1 /*
2  * Copyright 2024, 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 #pragma once
18 
19 #include <atomic>
20 
21 #include <android/IOMXBufferSource.h>
22 #include <aidl/android/media/IAidlBufferSource.h>
23 #include <aidl/android/media/IAidlNode.h>
24 #include <codec2/hidl/client.h>
25 #include <media/stagefright/foundation/Mutexed.h>
26 #include <media/stagefright/aidlpersistentsurface/C2NodeDef.h>
27 
28 namespace android {
29 
30 /**
31  * IOmxNode implementation around codec 2.0 component, only to be used in
32  * IGraphicBufferSource::configure. Only subset of IOmxNode API is implemented.
33  * As a result, one cannot expect this IOmxNode to work in any other usage than
34  * IGraphicBufferSource(if aidl hal is used, IAidlGraphicBufferSource).
35  */
36 struct C2NodeImpl {
37     explicit C2NodeImpl(const std::shared_ptr<Codec2Client::Component> &comp, bool aidl);
38     ~C2NodeImpl();
39 
40     // IOMXNode and/or IAidlNode
41     status_t freeNode();
42 
43     void onFirstInputFrame();
44     void getConsumerUsageBits(uint64_t *usage /* nonnull */);
45     void getInputBufferParams(
46             ::aidl::android::media::IAidlNode::InputBufferParams *params /* nonnull */);
47     void setConsumerUsageBits(uint64_t usage);
48     void setAdjustTimestampGapUs(int32_t gapUs);
49 
50     status_t setInputSurface(
51             const sp<IOMXBufferSource> &bufferSource);
52     status_t setAidlInputSurface(
53             const std::shared_ptr<::aidl::android::media::IAidlBufferSource> &aidlBufferSource);
54 
55     status_t submitBuffer(
56             uint32_t buffer, const sp<GraphicBuffer> &graphicBuffer,
57             uint32_t flags, int64_t timestamp, int fenceFd);
58     status_t onDataspaceChanged(uint32_t dataSpace, uint32_t pixelFormat);
59 
60     /**
61      * Returns underlying IOMXBufferSource object.
62      */
63     sp<IOMXBufferSource> getSource();
64 
65     /**
66      * Returns underlying IAidlBufferSource object.
67      */
68     std::shared_ptr<::aidl::android::media::IAidlBufferSource> getAidlSource();
69 
70     /**
71      * Configure the frame size.
72      */
73     void setFrameSize(uint32_t width, uint32_t height);
74 
75     /**
76      * Notify that the input buffer reference is no longer needed by the component.
77      * Clean up if necessary.
78      *
79      * \param index input work index
80      */
81     void onInputBufferDone(c2_cntr64_t index);
82 
83     /**
84      * Notify input buffer is emptied.
85      */
86     void onInputBufferEmptied();
87 
88     /**
89      * Returns dataspace information from GraphicBufferSource.
90      */
91     android_dataspace getDataspace();
92 
93     /**
94      * Returns dataspace information from GraphicBufferSource.
95      */
96     uint32_t getPixelFormat();
97 
98     /**
99      * Sets priority of the queue thread.
100      */
101     void setPriority(int priority);
102 
103 private:
104     std::weak_ptr<Codec2Client::Component> mComp;
105 
106     sp<IOMXBufferSource> mBufferSource;
107     std::shared_ptr<::aidl::android::media::IAidlBufferSource> mAidlBufferSource;
108 
109     std::shared_ptr<C2Allocator> mAllocator;
110     std::atomic_uint64_t mFrameIndex;
111     uint32_t mWidth;
112     uint32_t mHeight;
113     uint64_t mUsage;
114     Mutexed<android_dataspace> mDataspace;
115     Mutexed<uint32_t> mPixelFormat;
116 
117     // WORKAROUND: timestamp adjustment
118 
119     // if >0: this is the max timestamp gap, if <0: this is -1 times the fixed timestamp gap
120     // if 0: no timestamp adjustment is made
121     // note that C2OMXNode can be recycled between encoding sessions.
122     int32_t mAdjustTimestampGapUs;
123     bool mFirstInputFrame; // true for first input
124     c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame
125     c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
126 
127     // Tracks the status of buffers
128     struct BuffersTracker {
129         BuffersTracker() = default;
130 
131         // Keeps track of buffers that are used by the component. Maps timestamp -> ID
132         std::map<uint64_t, uint32_t> mIdsInUse;
133         // Keeps track of the buffer IDs that are available after being released from the component.
134         std::list<uint32_t> mAvailableIds;
135     };
136     Mutexed<BuffersTracker> mBuffersTracker;
137 
138     class QueueThread;
139     sp<QueueThread> mQueueThread;
140 
141     bool mAidlHal;
142 
143     bool hasBufferSource();
144     void notifyInputBufferEmptied(int32_t bufferId);
145 };
146 
147 }  // namespace android
148