1 /*
2  * Copyright (C) 2023 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 #include <list>
17 #include <mutex>
18 #include <queue>
19 #include <shared_mutex>
20 #include "avcodec_errors.h"
21 #include "avcodec_log.h"
22 #include "avcodec_trace.h"
23 #include "avcodec_video_encoder.h"
24 #include "buffer/avsharedmemory.h"
25 #include "buffer_utils.h"
26 #include "common/native_mfmagic.h"
27 #include "native_avbuffer.h"
28 #include "native_avcodec_base.h"
29 #include "native_avcodec_videoencoder.h"
30 #include "native_avmagic.h"
31 #include "native_window.h"
32 
33 namespace {
34 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "NativeVideoEncoder"};
35 constexpr size_t MAX_TEMPNUM = 64;
36 
37 using namespace OHOS::MediaAVCodec;
38 using namespace OHOS::Media;
39 class NativeVideoEncoderCallback;
40 
41 struct VideoEncoderObject : public OH_AVCodec {
VideoEncoderObject__anon6f1e29270110::VideoEncoderObject42     explicit VideoEncoderObject(const std::shared_ptr<AVCodecVideoEncoder> &encoder)
43         : OH_AVCodec(AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER), videoEncoder_(encoder)
44     {
45     }
46     ~VideoEncoderObject() = default;
47 
48     void ClearBufferList();
49     void StopCallback();
50     void FormatToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVFormat>> &tempMap);
51     void BufferToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> &tempMap);
52     void MemoryToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> &tempMap);
53 
54     const std::shared_ptr<AVCodecVideoEncoder> videoEncoder_;
55     std::queue<OHOS::sptr<MFObjectMagic>> tempList_;
56     std::unordered_map<uint32_t, OHOS::sptr<OH_AVFormat>> inputFormatMap_;
57     std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> outputMemoryMap_;
58     std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> inputMemoryMap_;
59     std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> outputBufferMap_;
60     std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> inputBufferMap_;
61     std::shared_ptr<NativeVideoEncoderCallback> callback_ = nullptr;
62     bool isSetMemoryCallback_ = false;
63     bool isSetBufferCallback_ = false;
64     std::atomic<bool> isEOS_ = false;
65     bool isInputSurfaceMode_ = false;
66     std::shared_mutex objListMutex_;
67 };
68 
69 class NativeVideoEncoderCallback : public AVCodecCallback,
70                                    public MediaCodecCallback,
71                                    public MediaCodecParameterCallback {
72 public:
NativeVideoEncoderCallback(OH_AVCodec * codec,struct OH_AVCodecAsyncCallback cb,void * userData)73     NativeVideoEncoderCallback(OH_AVCodec *codec, struct OH_AVCodecAsyncCallback cb, void *userData)
74         : codec_(codec), asyncCallback_(cb), userData_(userData)
75     {
76     }
77 
NativeVideoEncoderCallback(OH_AVCodec * codec,OH_VideoEncoder_OnNeedInputParameter onInputParameter,void * userData)78     NativeVideoEncoderCallback(OH_AVCodec *codec, OH_VideoEncoder_OnNeedInputParameter onInputParameter, void *userData)
79         : codec_(codec), onInputParameter_(onInputParameter), paramUserData_(userData)
80     {
81     }
82 
NativeVideoEncoderCallback(OH_AVCodec * codec,struct OH_AVCodecCallback cb,void * userData)83     NativeVideoEncoderCallback(OH_AVCodec *codec, struct OH_AVCodecCallback cb, void *userData)
84         : codec_(codec), callback_(cb), userData_(userData)
85     {
86     }
87     virtual ~NativeVideoEncoderCallback() = default;
88 
OnError(AVCodecErrorType errorType,int32_t errorCode)89     void OnError(AVCodecErrorType errorType, int32_t errorCode) override
90     {
91         std::shared_lock<std::shared_mutex> lock(mutex_);
92         (void)errorType;
93 
94         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
95         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
96         CHECK_AND_RETURN_LOG(asyncCallback_.onError != nullptr || callback_.onError != nullptr, "Callback is nullptr");
97         int32_t extErr = AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(errorCode));
98         if (asyncCallback_.onError != nullptr) {
99             asyncCallback_.onError(codec_, extErr, userData_);
100         } else if (callback_.onError != nullptr) {
101             callback_.onError(codec_, extErr, userData_);
102         }
103     }
104 
OnOutputFormatChanged(const Format & format)105     void OnOutputFormatChanged(const Format &format) override
106     {
107         std::shared_lock<std::shared_mutex> lock(mutex_);
108 
109         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
110         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
111         CHECK_AND_RETURN_LOG(asyncCallback_.onStreamChanged != nullptr || callback_.onStreamChanged != nullptr,
112                              "Callback is nullptr");
113         OHOS::sptr<OH_AVFormat> object = new (std::nothrow) OH_AVFormat(format);
114         CHECK_AND_RETURN_LOG(object != nullptr, "OH_AVFormat create failed");
115         // The object lifecycle is controlled by the current function stack
116         if (asyncCallback_.onStreamChanged != nullptr) {
117             asyncCallback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
118         } else if (callback_.onStreamChanged != nullptr) {
119             callback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
120         }
121     }
122 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)123     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override
124     {
125         std::shared_lock<std::shared_mutex> lock(mutex_);
126 
127         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
128         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
129         CHECK_AND_RETURN_LOG(asyncCallback_.onNeedInputData != nullptr, "Callback is nullptr");
130 
131         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
132         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Context video encoder is nullptr!");
133 
134         if (videoEncObj->isEOS_.load() || videoEncObj->isInputSurfaceMode_) {
135             AVCODEC_LOGD("At eos or surface mode, no buffer available");
136             return;
137         }
138         OH_AVMemory *data = GetTransData(codec_, index, buffer, false);
139         asyncCallback_.onNeedInputData(codec_, index, data, userData_);
140     }
141 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)142     void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
143                                  std::shared_ptr<AVSharedMemory> buffer) override
144     {
145         std::shared_lock<std::shared_mutex> lock(mutex_);
146 
147         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
148         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
149         CHECK_AND_RETURN_LOG(asyncCallback_.onNeedOutputData != nullptr, "Callback is nullptr");
150 
151         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
152         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Context video encoder is nullptr!");
153 
154         struct OH_AVCodecBufferAttr bufferAttr {
155             info.presentationTimeUs, info.size, info.offset, flag
156         };
157         // The bufferInfo lifecycle is controlled by the current function stack
158         OH_AVMemory *data = GetTransData(codec_, index, buffer, true);
159 
160         if (!((flag == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (flag == AVCODEC_BUFFER_FLAG_EOS))) {
161             AVCodecTrace::TraceEnd("OH::Frame", info.presentationTimeUs);
162         }
163         asyncCallback_.onNeedOutputData(codec_, index, data, &bufferAttr, userData_);
164     }
165 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)166     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
167     {
168         std::shared_lock<std::shared_mutex> lock(mutex_);
169 
170         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
171         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
172         CHECK_AND_RETURN_LOG(callback_.onNeedInputBuffer != nullptr, "Callback is nullptr");
173 
174         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
175         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Context video encoder is nullptr!");
176 
177         if (videoEncObj->isEOS_.load() || videoEncObj->isInputSurfaceMode_) {
178             AVCODEC_LOGD("At eos or surface mode, no buffer available");
179             return;
180         }
181         OH_AVBuffer *data = GetTransData(codec_, index, buffer, false);
182         callback_.onNeedInputBuffer(codec_, index, data, userData_);
183     }
184 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)185     void OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
186     {
187         std::shared_lock<std::shared_mutex> lock(mutex_);
188         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
189         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
190         CHECK_AND_RETURN_LOG(callback_.onNewOutputBuffer != nullptr, "Callback is nullptr");
191 
192         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
193         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Video encoder is nullptr!");
194 
195         OH_AVBuffer *data = GetTransData(codec_, index, buffer, true);
196 
197         if (!((buffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS))) {
198             AVCodecTrace::TraceEnd("OH::Frame", buffer->pts_);
199         }
200         callback_.onNewOutputBuffer(codec_, index, data, userData_);
201     }
202 
OnInputParameterAvailable(uint32_t index,std::shared_ptr<Format> parameter)203     void OnInputParameterAvailable(uint32_t index, std::shared_ptr<Format> parameter) override
204     {
205         std::shared_lock<std::shared_mutex> lock(mutex_);
206         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr!");
207         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, "Codec magic error!");
208         CHECK_AND_RETURN_LOG(onInputParameter_ != nullptr, "Callback is nullptr");
209 
210         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
211         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Video encoder is nullptr!");
212         if (videoEncObj->isEOS_.load()) {
213             AVCODEC_LOGD("At eos state, no buffer available");
214             return;
215         }
216         OH_AVFormat *data = GetTransData(codec_, index, parameter);
217         onInputParameter_(codec_, index, data, paramUserData_);
218     }
219 
StopCallback()220     void StopCallback()
221     {
222         std::lock_guard<std::shared_mutex> lock(mutex_);
223         codec_ = nullptr;
224     }
225 
UpdateCallback(const struct OH_AVCodecAsyncCallback & cb,void * userData)226     void UpdateCallback(const struct OH_AVCodecAsyncCallback &cb, void *userData)
227     {
228         std::lock_guard<std::shared_mutex> lock(mutex_);
229         userData_ = userData;
230         asyncCallback_ = cb;
231     }
232 
UpdateCallback(const OH_VideoEncoder_OnNeedInputParameter & onInputParameter,void * userData)233     void UpdateCallback(const OH_VideoEncoder_OnNeedInputParameter &onInputParameter, void *userData)
234     {
235         std::lock_guard<std::shared_mutex> lock(mutex_);
236         paramUserData_ = userData;
237         onInputParameter_ = onInputParameter;
238     }
239 
UpdateCallback(const struct OH_AVCodecCallback & cb,void * userData)240     void UpdateCallback(const struct OH_AVCodecCallback &cb, void *userData)
241     {
242         std::lock_guard<std::shared_mutex> lock(mutex_);
243         userData_ = userData;
244         callback_ = cb;
245     }
246 
247 private:
GetTransData(struct OH_AVCodec * codec,uint32_t & index,std::shared_ptr<AVSharedMemory> & memory,bool isOutput)248     OH_AVMemory *GetTransData(struct OH_AVCodec *codec, uint32_t &index, std::shared_ptr<AVSharedMemory> &memory,
249                               bool isOutput)
250     {
251         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
252         auto &memoryMap = isOutput ? videoEncObj->outputMemoryMap_ : videoEncObj->inputMemoryMap_;
253         {
254             std::shared_lock<std::shared_mutex> lock(videoEncObj->objListMutex_);
255             auto iter = memoryMap.find(index);
256             if (iter != memoryMap.end() && iter->second->IsEqualMemory(memory)) {
257                 return reinterpret_cast<OH_AVMemory *>(iter->second.GetRefPtr());
258             }
259         }
260 
261         OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
262         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "AV memory create failed");
263 
264         std::lock_guard<std::shared_mutex> lock(videoEncObj->objListMutex_);
265         auto iterAndRet = memoryMap.emplace(index, object);
266         if (!iterAndRet.second) {
267             auto &temp = iterAndRet.first->second;
268             temp->magic_ = MFMagic::MFMAGIC_UNKNOWN;
269             temp->memory_ = nullptr;
270             videoEncObj->tempList_.push(std::move(temp));
271             iterAndRet.first->second = object;
272             if (videoEncObj->tempList_.size() > MAX_TEMPNUM) {
273                 videoEncObj->tempList_.pop();
274             }
275         }
276         return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
277     }
278 
GetTransData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVBuffer> & buffer,bool isOutput)279     OH_AVBuffer *GetTransData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVBuffer> &buffer,
280                               bool isOutput)
281     {
282         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
283         auto &bufferMap = isOutput ? videoEncObj->outputBufferMap_ : videoEncObj->inputBufferMap_;
284         {
285             std::shared_lock<std::shared_mutex> lock(videoEncObj->objListMutex_);
286             auto iter = bufferMap.find(index);
287             if (iter != bufferMap.end() && iter->second->IsEqualBuffer(buffer)) {
288                 return reinterpret_cast<OH_AVBuffer *>(iter->second.GetRefPtr());
289             }
290         }
291 
292         OHOS::sptr<OH_AVBuffer> object = new (std::nothrow) OH_AVBuffer(buffer);
293         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new OH_AVBuffer");
294 
295         std::lock_guard<std::shared_mutex> lock(videoEncObj->objListMutex_);
296         auto iterAndRet = bufferMap.emplace(index, object);
297         if (!iterAndRet.second) {
298             auto &temp = iterAndRet.first->second;
299             temp->magic_ = MFMagic::MFMAGIC_UNKNOWN;
300             temp->buffer_ = nullptr;
301             videoEncObj->tempList_.push(std::move(temp));
302             iterAndRet.first->second = object;
303             if (videoEncObj->tempList_.size() > MAX_TEMPNUM) {
304                 videoEncObj->tempList_.pop();
305             }
306         }
307         return reinterpret_cast<OH_AVBuffer *>(object.GetRefPtr());
308     }
309 
GetTransData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<Format> & parameter)310     OH_AVFormat *GetTransData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<Format> &parameter)
311     {
312         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
313         {
314             std::shared_lock<std::shared_mutex> lock(videoEncObj->objListMutex_);
315             auto iter = videoEncObj->inputFormatMap_.find(index);
316             if (iter != videoEncObj->inputFormatMap_.end() && iter->second->format_.GetMeta() == parameter->GetMeta()) {
317                 return reinterpret_cast<OH_AVFormat *>(iter->second.GetRefPtr());
318             }
319         }
320         OHOS::sptr<OH_AVFormat> object = new (std::nothrow) OH_AVFormat();
321         object->format_ = std::move(*parameter);
322         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new OH_AVFormat");
323 
324         std::lock_guard<std::shared_mutex> lock(videoEncObj->objListMutex_);
325         auto iterAndRet = videoEncObj->inputFormatMap_.emplace(index, object);
326         if (!iterAndRet.second) {
327             auto &temp = iterAndRet.first->second;
328             temp->magic_ = MFMagic::MFMAGIC_UNKNOWN;
329             if (temp->outString_ != nullptr) {
330                 free(temp->outString_);
331                 temp->outString_ = nullptr;
332             }
333             if (temp->dumpInfo_ != nullptr) {
334                 free(temp->dumpInfo_);
335                 temp->dumpInfo_ = nullptr;
336             }
337             temp->format_ = Format();
338             videoEncObj->tempList_.push(std::move(temp));
339             iterAndRet.first->second = object;
340             if (videoEncObj->tempList_.size() > MAX_TEMPNUM) {
341                 videoEncObj->tempList_.pop();
342             }
343         }
344         return reinterpret_cast<OH_AVFormat *>(object.GetRefPtr());
345     }
346 
347     struct OH_AVCodec *codec_ = nullptr;
348     struct OH_AVCodecAsyncCallback asyncCallback_ = {nullptr, nullptr, nullptr, nullptr};
349     struct OH_AVCodecCallback callback_ = {nullptr, nullptr, nullptr, nullptr};
350     OH_VideoEncoder_OnNeedInputParameter onInputParameter_ = nullptr;
351     void *userData_ = nullptr;
352     void *paramUserData_ = nullptr;
353     std::shared_mutex mutex_;
354 };
355 
ClearBufferList()356 void VideoEncoderObject::ClearBufferList()
357 {
358     std::lock_guard<std::shared_mutex> lock(objListMutex_);
359     if (isSetBufferCallback_) {
360         BufferToTempFunc(inputBufferMap_);
361         BufferToTempFunc(outputBufferMap_);
362         inputBufferMap_.clear();
363         outputBufferMap_.clear();
364     } else if (isSetMemoryCallback_) {
365         MemoryToTempFunc(inputMemoryMap_);
366         MemoryToTempFunc(outputMemoryMap_);
367         inputMemoryMap_.clear();
368         outputMemoryMap_.clear();
369     }
370     if (inputFormatMap_.size() > 0) {
371         FormatToTempFunc(inputFormatMap_);
372         inputFormatMap_.clear();
373     }
374     while (tempList_.size() > MAX_TEMPNUM) {
375         tempList_.pop();
376     }
377 }
378 
StopCallback()379 void VideoEncoderObject::StopCallback()
380 {
381     if (callback_ == nullptr) {
382         return;
383     }
384     callback_->StopCallback();
385 }
386 
FormatToTempFunc(std::unordered_map<uint32_t,OHOS::sptr<OH_AVFormat>> & tempMap)387 void VideoEncoderObject::FormatToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVFormat>> &tempMap)
388 {
389     for (auto &val : tempMap) {
390         val.second->magic_ = MFMagic::MFMAGIC_UNKNOWN;
391         if (val.second->outString_ != nullptr) {
392             free(val.second->outString_);
393             val.second->outString_ = nullptr;
394         }
395         if (val.second->dumpInfo_ != nullptr) {
396             free(val.second->dumpInfo_);
397             val.second->dumpInfo_ = nullptr;
398         }
399         val.second->format_ = Format();
400         tempList_.push(std::move(val.second));
401     }
402 }
403 
BufferToTempFunc(std::unordered_map<uint32_t,OHOS::sptr<OH_AVBuffer>> & tempMap)404 void VideoEncoderObject::BufferToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> &tempMap)
405 {
406     for (auto &val : tempMap) {
407         val.second->magic_ = MFMagic::MFMAGIC_UNKNOWN;
408         val.second->buffer_ = nullptr;
409         tempList_.push(std::move(val.second));
410     }
411 }
412 
MemoryToTempFunc(std::unordered_map<uint32_t,OHOS::sptr<OH_AVMemory>> & tempMap)413 void VideoEncoderObject::MemoryToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> &tempMap)
414 {
415     for (auto &val : tempMap) {
416         val.second->magic_ = MFMagic::MFMAGIC_UNKNOWN;
417         val.second->memory_ = nullptr;
418         tempList_.push(std::move(val.second));
419     }
420 }
421 } // namespace
422 
423 namespace OHOS {
424 namespace MediaAVCodec {
425 #ifdef __cplusplus
426 extern "C" {
427 #endif
OH_VideoEncoder_CreateByMime(const char * mime)428 struct OH_AVCodec *OH_VideoEncoder_CreateByMime(const char *mime)
429 {
430     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Mime is nullptr!");
431 
432     std::shared_ptr<AVCodecVideoEncoder> videoEncoder = VideoEncoderFactory::CreateByMime(mime);
433     CHECK_AND_RETURN_RET_LOG(videoEncoder != nullptr, nullptr, "Video encoder create by mime failed");
434 
435     struct VideoEncoderObject *object = new (std::nothrow) VideoEncoderObject(videoEncoder);
436     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video encoder create by mime failed");
437 
438     return object;
439 }
440 
OH_VideoEncoder_CreateByName(const char * name)441 struct OH_AVCodec *OH_VideoEncoder_CreateByName(const char *name)
442 {
443     CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "Name is nullptr!");
444 
445     std::shared_ptr<AVCodecVideoEncoder> videoEncoder = VideoEncoderFactory::CreateByName(name);
446     CHECK_AND_RETURN_RET_LOG(videoEncoder != nullptr, nullptr, "Video encoder create by name failed");
447 
448     struct VideoEncoderObject *object = new (std::nothrow) VideoEncoderObject(videoEncoder);
449     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video encoder create by name failed");
450 
451     return object;
452 }
453 
OH_VideoEncoder_Destroy(struct OH_AVCodec * codec)454 OH_AVErrCode OH_VideoEncoder_Destroy(struct OH_AVCodec *codec)
455 {
456     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
457     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
458                              "Codec magic error!");
459 
460     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
461 
462     if (videoEncObj != nullptr && videoEncObj->videoEncoder_ != nullptr) {
463         int32_t ret = videoEncObj->videoEncoder_->Release();
464         videoEncObj->StopCallback();
465         videoEncObj->ClearBufferList();
466         if (ret != AVCS_ERR_OK) {
467             AVCODEC_LOGE("Video encoder destroy failed!");
468             delete codec;
469             return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
470         }
471     } else {
472         AVCODEC_LOGD("Video encoder is nullptr!");
473     }
474 
475     delete codec;
476     return AV_ERR_OK;
477 }
478 
OH_VideoEncoder_Configure(struct OH_AVCodec * codec,struct OH_AVFormat * format)479 OH_AVErrCode OH_VideoEncoder_Configure(struct OH_AVCodec *codec, struct OH_AVFormat *format)
480 {
481     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
482     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
483                              "Codec magic error!");
484     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
485     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "Format magic error!");
486 
487     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
488     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
489 
490     int32_t ret = videoEncObj->videoEncoder_->Configure(format->format_);
491     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
492                              "Video encoder configure failed!");
493 
494     return AV_ERR_OK;
495 }
496 
OH_VideoEncoder_Prepare(struct OH_AVCodec * codec)497 OH_AVErrCode OH_VideoEncoder_Prepare(struct OH_AVCodec *codec)
498 {
499     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
500     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
501                              "Codec magic error!");
502 
503     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
504     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
505 
506     int32_t ret = videoEncObj->videoEncoder_->Prepare();
507     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
508                              "Video encoder prepare failed!");
509 
510     return AV_ERR_OK;
511 }
512 
OH_VideoEncoder_Start(struct OH_AVCodec * codec)513 OH_AVErrCode OH_VideoEncoder_Start(struct OH_AVCodec *codec)
514 {
515     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
516     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
517                              "Codec magic error!");
518 
519     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
520     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
521 
522     videoEncObj->isEOS_.store(false);
523     int32_t ret = videoEncObj->videoEncoder_->Start();
524     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
525                              "Video encoder start failed!");
526 
527     return AV_ERR_OK;
528 }
529 
OH_VideoEncoder_Stop(struct OH_AVCodec * codec)530 OH_AVErrCode OH_VideoEncoder_Stop(struct OH_AVCodec *codec)
531 {
532     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
533     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
534                              "Codec magic error!");
535 
536     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
537     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
538 
539     int32_t ret = videoEncObj->videoEncoder_->Stop();
540     if (ret != AVCS_ERR_OK) {
541         AVCODEC_LOGE("Video encoder stop failed");
542         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
543     }
544     videoEncObj->ClearBufferList();
545     return AV_ERR_OK;
546 }
547 
OH_VideoEncoder_Flush(struct OH_AVCodec * codec)548 OH_AVErrCode OH_VideoEncoder_Flush(struct OH_AVCodec *codec)
549 {
550     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
551     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
552                              "Codec magic error!");
553 
554     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
555     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
556 
557     int32_t ret = videoEncObj->videoEncoder_->Flush();
558     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
559                              "Video encoder flush failed!");
560     videoEncObj->ClearBufferList();
561     return AV_ERR_OK;
562 }
563 
OH_VideoEncoder_Reset(struct OH_AVCodec * codec)564 OH_AVErrCode OH_VideoEncoder_Reset(struct OH_AVCodec *codec)
565 {
566     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
567     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
568                              "Codec magic error!");
569 
570     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
571     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
572 
573     int32_t ret = videoEncObj->videoEncoder_->Reset();
574     if (ret != AVCS_ERR_OK) {
575         AVCODEC_LOGE("Video encoder reset failed");
576         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
577     }
578     videoEncObj->ClearBufferList();
579     return AV_ERR_OK;
580 }
581 
OH_VideoEncoder_GetSurface(OH_AVCodec * codec,OHNativeWindow ** window)582 OH_AVErrCode OH_VideoEncoder_GetSurface(OH_AVCodec *codec, OHNativeWindow **window)
583 {
584     CHECK_AND_RETURN_RET_LOG(codec != nullptr && window != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
585     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
586                              "Codec magic error!");
587 
588     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
589     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
590 
591     OHOS::sptr<OHOS::Surface> surface = videoEncObj->videoEncoder_->CreateInputSurface();
592     CHECK_AND_RETURN_RET_LOG(surface != nullptr, AV_ERR_OPERATE_NOT_PERMIT, "Video encoder get surface failed!");
593 
594     *window = CreateNativeWindowFromSurface(&surface);
595     CHECK_AND_RETURN_RET_LOG(*window != nullptr, AV_ERR_INVALID_VAL, "Video encoder get surface failed!");
596     videoEncObj->isInputSurfaceMode_ = true;
597 
598     return AV_ERR_OK;
599 }
600 
OH_VideoEncoder_GetOutputDescription(struct OH_AVCodec * codec)601 OH_AVFormat *OH_VideoEncoder_GetOutputDescription(struct OH_AVCodec *codec)
602 {
603     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
604     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr, "Codec magic error!");
605 
606     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
607     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video encoder is nullptr!");
608 
609     Format format;
610     int32_t ret = videoEncObj->videoEncoder_->GetOutputFormat(format);
611     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video encoder get output description failed!");
612 
613     OH_AVFormat *avFormat = OH_AVFormat_Create();
614     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video encoder get output description failed!");
615     avFormat->format_ = format;
616 
617     return avFormat;
618 }
619 
OH_VideoEncoder_FreeOutputData(struct OH_AVCodec * codec,uint32_t index)620 OH_AVErrCode OH_VideoEncoder_FreeOutputData(struct OH_AVCodec *codec, uint32_t index)
621 {
622     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
623     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
624                              "Codec magic error!");
625 
626     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
627     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
628     CHECK_AND_RETURN_RET_LOG(videoEncObj->callback_ != nullptr, AV_ERR_INVALID_STATE,
629                              "The callback of OH_AVMemory is nullptr!");
630 
631     int32_t ret = videoEncObj->videoEncoder_->ReleaseOutputBuffer(index);
632     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
633                              "Video encoder free output data failed!");
634 
635     return AV_ERR_OK;
636 }
637 
OH_VideoEncoder_FreeOutputBuffer(struct OH_AVCodec * codec,uint32_t index)638 OH_AVErrCode OH_VideoEncoder_FreeOutputBuffer(struct OH_AVCodec *codec, uint32_t index)
639 {
640     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
641     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
642                              "Codec magic error!");
643 
644     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
645     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
646     CHECK_AND_RETURN_RET_LOG(videoEncObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
647                              "The callback of OH_AVBuffer is nullptr!");
648 
649     int32_t ret = videoEncObj->videoEncoder_->ReleaseOutputBuffer(index);
650     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
651                              "Video encoder free output data failed!");
652 
653     return AV_ERR_OK;
654 }
655 
OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec * codec)656 OH_AVErrCode OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec *codec)
657 {
658     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
659     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
660                              "Codec magic error!");
661 
662     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
663     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
664 
665     int32_t ret = videoEncObj->videoEncoder_->NotifyEos();
666     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
667                              "Video encoder notify end of stream failed!");
668 
669     videoEncObj->isEOS_.store(true);
670     return AV_ERR_OK;
671 }
672 
OH_VideoEncoder_SetParameter(struct OH_AVCodec * codec,struct OH_AVFormat * format)673 OH_AVErrCode OH_VideoEncoder_SetParameter(struct OH_AVCodec *codec, struct OH_AVFormat *format)
674 {
675     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
676     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
677                              "Codec magic error!");
678     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
679     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "Format magic error!");
680 
681     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
682     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
683 
684     int32_t ret = videoEncObj->videoEncoder_->SetParameter(format->format_);
685     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
686                              "Video encoder set parameter failed!");
687 
688     return AV_ERR_OK;
689 }
690 
OH_VideoEncoder_SetCallback(struct OH_AVCodec * codec,struct OH_AVCodecAsyncCallback callback,void * userData)691 OH_AVErrCode OH_VideoEncoder_SetCallback(struct OH_AVCodec *codec, struct OH_AVCodecAsyncCallback callback,
692                                          void *userData)
693 {
694     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
695     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
696                              "Codec magic error!");
697 
698     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
699     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
700 
701     if (videoEncObj->callback_ != nullptr) {
702         videoEncObj->callback_->UpdateCallback(callback, userData);
703     } else {
704         videoEncObj->callback_ = std::make_shared<NativeVideoEncoderCallback>(codec, callback, userData);
705     }
706     int32_t ret =
707         videoEncObj->videoEncoder_->SetCallback(std::static_pointer_cast<AVCodecCallback>(videoEncObj->callback_));
708     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
709                              "Video encoder set callback failed!");
710     videoEncObj->isSetMemoryCallback_ = true;
711     return AV_ERR_OK;
712 }
713 
OH_VideoEncoder_RegisterCallback(struct OH_AVCodec * codec,struct OH_AVCodecCallback callback,void * userData)714 OH_AVErrCode OH_VideoEncoder_RegisterCallback(struct OH_AVCodec *codec, struct OH_AVCodecCallback callback,
715                                               void *userData)
716 {
717     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
718     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
719                              "Codec magic error!");
720     CHECK_AND_RETURN_RET_LOG(callback.onNewOutputBuffer != nullptr, AV_ERR_INVALID_VAL,
721                              "Callback onNewOutputBuffer is nullptr");
722 
723     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
724     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
725 
726     if (videoEncObj->callback_ != nullptr) {
727         videoEncObj->callback_->UpdateCallback(callback, userData);
728     } else {
729         videoEncObj->callback_ = std::make_shared<NativeVideoEncoderCallback>(codec, callback, userData);
730     }
731     int32_t ret =
732         videoEncObj->videoEncoder_->SetCallback(std::static_pointer_cast<MediaCodecCallback>(videoEncObj->callback_));
733     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
734                              "Video encoder register callback failed!");
735     videoEncObj->isSetBufferCallback_ = true;
736     return AV_ERR_OK;
737 }
738 
OH_VideoEncoder_RegisterParameterCallback(OH_AVCodec * codec,OH_VideoEncoder_OnNeedInputParameter onInputParameter,void * userData)739 OH_AVErrCode OH_VideoEncoder_RegisterParameterCallback(OH_AVCodec *codec,
740                                                        OH_VideoEncoder_OnNeedInputParameter onInputParameter,
741                                                        void *userData)
742 {
743     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
744     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
745                              "Codec magic error!");
746     CHECK_AND_RETURN_RET_LOG(onInputParameter != nullptr, AV_ERR_INVALID_VAL, "Callback onInputParameter is nullptr");
747 
748     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
749     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
750 
751     if (videoEncObj->callback_ != nullptr) {
752         videoEncObj->callback_->UpdateCallback(onInputParameter, userData);
753     } else {
754         videoEncObj->callback_ = std::make_shared<NativeVideoEncoderCallback>(codec, onInputParameter, userData);
755     }
756     int32_t ret = videoEncObj->videoEncoder_->SetCallback(
757         std::static_pointer_cast<MediaCodecParameterCallback>(videoEncObj->callback_));
758     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
759                              "Video encoder register parameter callback failed!");
760     return AV_ERR_OK;
761 }
762 
OH_VideoEncoder_PushInputData(struct OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)763 OH_AVErrCode OH_VideoEncoder_PushInputData(struct OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
764 {
765     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
766     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
767                              "Codec magic error!");
768     CHECK_AND_RETURN_RET_LOG(attr.size >= 0, AV_ERR_INVALID_VAL, "Invalid buffer size!");
769 
770     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
771     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
772     CHECK_AND_RETURN_RET_LOG(videoEncObj->callback_ != nullptr, AV_ERR_INVALID_STATE,
773                              "The callback of OH_AVMemory is nullptr!");
774 
775     if (!((attr.flags == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (attr.flags == AVCODEC_BUFFER_FLAG_EOS))) {
776         AVCodecTrace::TraceBegin("OH::Frame", attr.pts);
777     }
778 
779     struct AVCodecBufferInfo bufferInfo;
780     bufferInfo.presentationTimeUs = attr.pts;
781     bufferInfo.size = attr.size;
782     bufferInfo.offset = attr.offset;
783     enum AVCodecBufferFlag bufferFlag = static_cast<enum AVCodecBufferFlag>(attr.flags);
784 
785     int32_t ret = videoEncObj->videoEncoder_->QueueInputBuffer(index, bufferInfo, bufferFlag);
786     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
787                              "Video encoder push input data failed!");
788     if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
789         videoEncObj->isEOS_.store(true);
790     }
791 
792     return AV_ERR_OK;
793 }
794 
OH_VideoEncoder_PushInputBuffer(struct OH_AVCodec * codec,uint32_t index)795 OH_AVErrCode OH_VideoEncoder_PushInputBuffer(struct OH_AVCodec *codec, uint32_t index)
796 {
797     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Input codec is nullptr!");
798     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL, "magic error!");
799 
800     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
801     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "videoEncoder_ is nullptr!");
802     CHECK_AND_RETURN_RET_LOG(videoEncObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
803                              "The callback of OH_AVBuffer is nullptr!");
804 
805     {
806         std::shared_lock<std::shared_mutex> lock(videoEncObj->objListMutex_);
807         auto bufferIter = videoEncObj->inputBufferMap_.find(index);
808         CHECK_AND_RETURN_RET_LOG(bufferIter != videoEncObj->inputBufferMap_.end(), AV_ERR_INVALID_VAL,
809                                  "Invalid buffer index");
810         auto buffer = bufferIter->second->buffer_;
811         if (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
812             videoEncObj->isEOS_.store(true);
813             AVCODEC_LOGD("Set eos status to true");
814         }
815         if (!((buffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS))) {
816             AVCodecTrace::TraceBegin("OH::Frame", buffer->pts_);
817         }
818     }
819 
820     int32_t ret = videoEncObj->videoEncoder_->QueueInputBuffer(index);
821     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
822                              "videoEncoder QueueInputBuffer failed!");
823     return AV_ERR_OK;
824 }
825 
OH_VideoEncoder_PushInputParameter(OH_AVCodec * codec,uint32_t index)826 OH_AVErrCode OH_VideoEncoder_PushInputParameter(OH_AVCodec *codec, uint32_t index)
827 {
828     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Input codec is nullptr!");
829     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL, "magic error!");
830 
831     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
832     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "videoEncoder_ is nullptr!");
833 
834     int32_t ret = videoEncObj->videoEncoder_->QueueInputParameter(index);
835     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
836                              "videoEncoder QueueInputParameter failed!");
837     return AV_ERR_OK;
838 }
839 
OH_VideoEncoder_GetInputDescription(OH_AVCodec * codec)840 OH_AVFormat *OH_VideoEncoder_GetInputDescription(OH_AVCodec *codec)
841 {
842     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
843     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr, "Codec magic error!");
844 
845     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
846     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video encoder is nullptr!");
847 
848     Format format;
849     int32_t ret = videoEncObj->videoEncoder_->GetInputFormat(format);
850     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video encoder get input description failed!");
851 
852     OH_AVFormat *avFormat = OH_AVFormat_Create();
853     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video encoder get input description failed!");
854     avFormat->format_ = format;
855 
856     return avFormat;
857 }
858 
OH_VideoEncoder_IsValid(OH_AVCodec * codec,bool * isValid)859 OH_AVErrCode OH_VideoEncoder_IsValid(OH_AVCodec *codec, bool *isValid)
860 {
861     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
862     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
863                              "Codec magic error!");
864     CHECK_AND_RETURN_RET_LOG(isValid != nullptr, AV_ERR_INVALID_VAL, "Input isValid is nullptr!");
865     *isValid = true;
866     return AV_ERR_OK;
867 }
868 }
869 } // namespace MediaAVCodec
870 } // namespace OHOS