• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CODEC_BUFFER_CIRCULAR_H
17 #define CODEC_BUFFER_CIRCULAR_H
18 
19 #include <queue>
20 #include <shared_mutex>
21 #include <string>
22 #include "avcodec_common.h"
23 #include "avcodec_dfx_component.h"
24 
25 namespace OHOS {
26 namespace MediaAVCodec {
27 class BufferConverter;
28 class CodecBufferCircular : public AVCodecDfxComponent {
29 public:
30     CodecBufferCircular() = default;
31     ~CodecBufferCircular();
32 
33     // Configure circular
34     void SetConverter(std::shared_ptr<BufferConverter> &converter);
35     int32_t SetCallback(const std::shared_ptr<AVCodecCallback> &callback);
36     int32_t SetCallback(const std::shared_ptr<MediaCodecCallback> &callback);
37     int32_t SetCallback(const std::shared_ptr<MediaCodecParameterCallback> &callback);
38     int32_t SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> &callback);
39 
40     void SetIsRunning(bool isRunning);
41     bool CanEnableSyncMode();
42     bool CanEnableAsyncMode();
43     void EnableSyncMode();
44     void EnableAsyncMode();
45     bool IsSyncMode();
46     void ResetFlag();
47 
48     // Caches
49     void ClearCaches();
50     void FlushCaches();
51 
52     // Sycn mode interface
53     int32_t QueryInputBuffer(uint32_t &index, int64_t timeoutUs);
54     int32_t QueryOutputBuffer(uint32_t &index, int64_t timeoutUs);
55     std::shared_ptr<AVBuffer> GetInputBuffer(uint32_t index);
56     std::shared_ptr<AVBuffer> GetOutputBuffer(uint32_t index);
57 
58     // Handle buffer before send to proxy
59     int32_t HandleInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag);
60     int32_t HandleInputBuffer(uint32_t index);
61     int32_t HandleOutputBuffer(uint32_t index);
62     void QueueInputBufferDone(uint32_t index);
63     void ReleaseOutputBufferDone(uint32_t index);
64     void NotifyEos();
65 
66     // Callback
67     void OnError(AVCodecErrorType errorType, int32_t errorCode);
68     void OnOutputFormatChanged(const Format &format);
69     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer);
70     void OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer);
71     void OnOutputBufferBinded(std::map<uint32_t, sptr<SurfaceBuffer>> &bufferMap);
72     void OnOutputBufferUnbinded();
73 
74 private:
75     typedef enum : uint8_t {
76         FLAG_NONE = 0,
77         FLAG_IS_RUNNING = 1 << 0,
78         FLAG_IS_SYNC = 1 << 1,
79         FLAG_SYNC_ASYNC_CONFIGURED = 1 << 2,
80         FLAG_ERROR = 1 << 3,
81         FLAG_INPUT_EOS = 1 << 4,
82         FLAG_OUTPUT_EOS = 1 << 5,
83     } CodecCircularFlag;
84     typedef enum : uint8_t {
85         OWNED_BY_SERVER = 0,
86         OWNED_BY_CLIENT = 1,
87         OWNED_BY_USER = 2,
88     } BufferOwner;
89 
90     typedef enum : uint8_t {
91         MODE_ASYNC,
92         MODE_SYNC,
93     } ModeType;
94 
95     typedef struct BufferItem {
96         std::shared_ptr<AVBuffer> buffer = nullptr;
97         std::shared_ptr<AVSharedMemory> memory = nullptr;
98         std::shared_ptr<Format> parameter = nullptr;
99         std::shared_ptr<Format> attribute = nullptr;
100         BufferOwner owner = OWNED_BY_SERVER;
101 
102         // Used in QueueInputBuffer/ReleaseOutputBuffer
103         uint32_t flag = 0;
104         int32_t size = 0;
105         int64_t pts = 0;
106     } BufferItem;
107     using BufferCache = std::unordered_map<uint32_t, BufferItem>;
108     using BufferCacheIter = BufferCache::iterator;
109 
110     // Common
111     static std::shared_ptr<Format> GetParameter(BufferCacheIter &iter);
112     static std::shared_ptr<Format> GetAttribute(BufferCacheIter &iter);
113     static const std::string &OwnerToString(BufferOwner owner);
114     void PrintCaches(bool isOutput);
115     void ClearOutputBufferOwnedByCodec();
116     bool HasFlag(const CodecCircularFlag flag);
117     void AddFlag(const CodecCircularFlag flag);
118     void RemoveFlag(const CodecCircularFlag flag);
119 
120     template <ModeType mode>
CanEnableMode()121     inline bool CanEnableMode()
122     {
123         bool isUnconfigured = !(flags_ & FLAG_SYNC_ASYNC_CONFIGURED);
124         bool modeMatched = !(flags_ & FLAG_IS_SYNC);
125         if constexpr (mode == MODE_SYNC) {
126             modeMatched = (flags_ & FLAG_IS_SYNC);
127         }
128         return isUnconfigured || modeMatched;
129     }
130 
131     template <ModeType mode>
EnableMode()132     inline void EnableMode()
133     {
134         if constexpr (mode == MODE_SYNC) {
135             flags_ |= FLAG_IS_SYNC;
136         }
137         flags_ |= FLAG_SYNC_ASYNC_CONFIGURED;
138     }
139 
140     BufferCache inCache_;
141     BufferCache outCache_;
142     std::mutex inMutex_;
143     std::mutex outMutex_;
144     std::atomic<uint8_t> flags_ = FLAG_NONE;
145 
146     // Async mode
147     void AsyncOnError(AVCodecErrorType errorType, int32_t errorCode);
148     void AsyncOnOutputFormatChanged(const Format &format);
149     void AsyncOnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> &buffer);
150     void AsyncOnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> &buffer);
151     void ConvertToSharedMemory(const std::shared_ptr<AVBuffer> &buffer, std::shared_ptr<AVSharedMemory> &memory);
152 
153     std::shared_ptr<AVCodecCallback> callback_ = nullptr;
154     std::shared_ptr<MediaCodecCallback> mediaCb_ = nullptr;
155     std::shared_ptr<MediaCodecParameterCallback> paramCb_ = nullptr;
156     std::shared_ptr<MediaCodecParameterWithAttrCallback> attrCb_ = nullptr;
157     std::shared_ptr<BufferConverter> converter_ = nullptr;
158 
159     // Sync mode
160     typedef enum : uint8_t {
161         EVENT_UNKNOWN,
162         EVENT_OUTPUT_BUFFER,
163         EVENT_INPUT_BUFFER,
164         EVENT_STREAM_CHANGED,
165     } EventType;
166     typedef struct Event {
167         EventType type = EVENT_UNKNOWN;
168         uint32_t index = 0;
169     } Event;
170     using EventQueue = std::queue<Event>;
171 
172     void SyncOnError(AVCodecErrorType errorType, int32_t errorCode);
173     void SyncOnOutputFormatChanged(const Format &format);
174     void SyncOnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> &buffer);
175     void SyncOnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> &buffer);
176     int32_t QueryInputIndex(uint32_t &index, int64_t timeoutUs);
177     int32_t QueryOutputIndex(uint32_t &index, int64_t timeoutUs);
178     bool WaitForInputBuffer(std::unique_lock<std::mutex> &lock, int64_t timeoutUs);
179     bool WaitForOutputBuffer(std::unique_lock<std::mutex> &lock, int64_t timeoutUs);
180 
181     std::condition_variable inCond_;
182     std::condition_variable outCond_;
183     EventQueue inQueue_;
184     EventQueue outQueue_;
185     int32_t lastError_ = 0;
186 };
187 } // namespace MediaAVCodec
188 } // namespace OHOS
189 #endif