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