• 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 <shared_mutex>
19 #include "avcodec_dfx.h"
20 #include "avcodec_errors.h"
21 #include "avcodec_log.h"
22 #include "avcodec_video_encoder.h"
23 #include "avsharedmemory.h"
24 #include "native_window.h"
25 #include "native_avcodec_base.h"
26 #include "native_avcodec_videoencoder.h"
27 #include "native_avmagic.h"
28 
29 
30 namespace {
31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "NativeVideoEncoder"};
32 }
33 
34 using namespace OHOS::MediaAVCodec;
35 class NativeVideoEncoderCallback;
36 
37 struct VideoEncoderObject : public OH_AVCodec {
VideoEncoderObjectVideoEncoderObject38     explicit VideoEncoderObject(const std::shared_ptr<AVCodecVideoEncoder> &encoder)
39         : OH_AVCodec(AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER), videoEncoder_(encoder) {}
40     ~VideoEncoderObject() = default;
41 
42     const std::shared_ptr<AVCodecVideoEncoder> videoEncoder_;
43     std::list<OHOS::sptr<OH_AVMemory>> memoryObjList_;
44     std::shared_ptr<NativeVideoEncoderCallback> callback_ = nullptr;
45     std::atomic<bool> isFlushing_ = false;
46     std::atomic<bool> isFlushed_ = false;
47     std::atomic<bool> isStop_ = false;
48     std::atomic<bool> isEOS_ = false;
49     bool isInputSurfaceMode_ = false;
50     std::atomic<bool> isFirstFrameIn_ = true;
51     std::atomic<bool> isFirstFrameOut_ = true;
52     std::shared_mutex memoryObjListMutex_;
53 };
54 
55 class NativeVideoEncoderCallback : public AVCodecCallback {
56 public:
NativeVideoEncoderCallback(OH_AVCodec * codec,struct OH_AVCodecAsyncCallback cb,void * userData)57     NativeVideoEncoderCallback(OH_AVCodec *codec, struct OH_AVCodecAsyncCallback cb, void *userData)
58         : codec_(codec), callback_(cb), userData_(userData) {}
59     virtual ~NativeVideoEncoderCallback() = default;
60 
OnError(AVCodecErrorType errorType,int32_t errorCode)61     void OnError(AVCodecErrorType errorType, int32_t errorCode) override
62     {
63         std::unique_lock<std::shared_mutex> lock(mutex_);
64         (void)errorType;
65 
66         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
67         CHECK_AND_RETURN_LOG(callback_.onError != nullptr, "Callback is nullptr");
68         int32_t extErr = AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(errorCode));
69         callback_.onError(codec_, extErr, userData_);
70     }
71 
OnOutputFormatChanged(const Format & format)72     void OnOutputFormatChanged(const Format &format) override
73     {
74         std::unique_lock<std::shared_mutex> lock(mutex_);
75 
76         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
77         CHECK_AND_RETURN_LOG(callback_.onStreamChanged != nullptr, "Callback is nullptr");
78         OHOS::sptr<OH_AVFormat> object = new(std::nothrow) OH_AVFormat(format);
79         // The object lifecycle is controlled by the current function stack
80         callback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
81     }
82 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)83     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override
84     {
85         std::shared_lock<std::shared_mutex> lock(mutex_);
86 
87         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
88         CHECK_AND_RETURN_LOG(callback_.onNeedInputData != nullptr, "Callback is nullptr");
89 
90         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
91         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Context video decoder is nullptr!");
92 
93         if (videoEncObj->isFlushing_.load() || videoEncObj->isFlushed_.load() || videoEncObj->isStop_.load() ||
94             videoEncObj->isEOS_.load()) {
95             AVCODEC_LOGD("At flush, eos or stop, no buffer available");
96             return;
97         }
98         OH_AVMemory *data = nullptr;
99         if (!videoEncObj->isInputSurfaceMode_) {
100             data = GetInputData(codec_, index, buffer);
101         }
102         callback_.onNeedInputData(codec_, index, data, userData_);
103     }
104 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)105     void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
106                                  std::shared_ptr<AVSharedMemory> buffer) 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(callback_.onNeedOutputData != nullptr, "Callback is nullptr");
112 
113         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec_);
114         CHECK_AND_RETURN_LOG(videoEncObj->videoEncoder_ != nullptr, "Context video decoder is nullptr!");
115 
116         if (videoEncObj->isFlushing_.load() || videoEncObj->isFlushed_.load() || videoEncObj->isStop_.load()) {
117             AVCODEC_LOGD("At flush or stop, ignore");
118             return;
119         }
120 
121         struct OH_AVCodecBufferAttr bufferAttr { info.presentationTimeUs, info.size, info.offset, flag };
122         // The bufferInfo lifecycle is controlled by the current function stack
123         OH_AVMemory *data = GetOutputData(codec_, index, buffer);
124 
125         if (flag != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
126             if (videoEncObj->isFirstFrameOut_) {
127                 AVCodecTrace::TraceEnd("OH::FirstFrame", info.presentationTimeUs);
128                 videoEncObj->isFirstFrameOut_ = false;
129             } else {
130                 AVCodecTrace::TraceEnd("OH::Frame", info.presentationTimeUs);
131             }
132         }
133         if (flag == AVCODEC_BUFFER_FLAG_EOS) {
134             videoEncObj->isFirstFrameIn_ = true;
135             videoEncObj->isFirstFrameOut_ = true;
136         }
137         callback_.onNeedOutputData(codec_, index, data, &bufferAttr, userData_);
138     }
139 
StopCallback()140     void StopCallback()
141     {
142         std::unique_lock<std::shared_mutex> lock(mutex_);
143         codec_ = nullptr;
144     }
145 
146 private:
GetInputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)147     OH_AVMemory *GetInputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
148     {
149         CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
150         CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr, "Codec magic error!");
151 
152         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
153         CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video decoder is nullptr!");
154         CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr, "Memory is nullptr, get input buffer failed!");
155 
156         {
157             std::shared_lock<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
158             for (auto &memoryObj : videoEncObj->memoryObjList_) {
159                 if (memoryObj->IsEqualMemory(memory)) {
160                     return reinterpret_cast<OH_AVMemory *>(memoryObj.GetRefPtr());
161                 }
162             }
163         }
164 
165         OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
166         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "AV memory create failed");
167 
168         std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
169         videoEncObj->memoryObjList_.push_back(object);
170         return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
171     }
172 
GetOutputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)173     OH_AVMemory *GetOutputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
174     {
175         CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
176         CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr, "Codec magic error!");
177 
178         struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
179         CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video encoder is nullptr!");
180         if (memory == nullptr) { return nullptr; }
181 
182         {
183             std::shared_lock<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
184             for (auto &memoryObj : videoEncObj->memoryObjList_) {
185                 if (memoryObj->IsEqualMemory(memory)) {
186                     return reinterpret_cast<OH_AVMemory *>(memoryObj.GetRefPtr());
187                 }
188             }
189         }
190 
191         OHOS::sptr<OH_AVMemory> object = new(std::nothrow) OH_AVMemory(memory);
192         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "AV memory create failed");
193 
194         std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
195         videoEncObj->memoryObjList_.push_back(object);
196         return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
197     }
198 
199     struct OH_AVCodec *codec_;
200     struct OH_AVCodecAsyncCallback callback_;
201     void *userData_;
202     std::shared_mutex mutex_;
203 };
204 
OH_VideoEncoder_CreateByMime(const char * mime)205 struct OH_AVCodec *OH_VideoEncoder_CreateByMime(const char *mime)
206 {
207     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Mime is nullptr!");
208 
209     std::shared_ptr<AVCodecVideoEncoder> videoEncoder = VideoEncoderFactory::CreateByMime(mime);
210     CHECK_AND_RETURN_RET_LOG(videoEncoder != nullptr, nullptr, "Video encoder create by mime failed");
211 
212     struct VideoEncoderObject *object = new(std::nothrow) VideoEncoderObject(videoEncoder);
213     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video encoder create by mime failed");
214 
215     return object;
216 }
217 
OH_VideoEncoder_CreateByName(const char * name)218 struct OH_AVCodec *OH_VideoEncoder_CreateByName(const char *name)
219 {
220     CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "Name is nullptr!");
221 
222     std::shared_ptr<AVCodecVideoEncoder> videoEncoder = VideoEncoderFactory::CreateByName(name);
223     CHECK_AND_RETURN_RET_LOG(videoEncoder != nullptr, nullptr, "Video encoder create by name failed");
224 
225     struct VideoEncoderObject *object = new(std::nothrow) VideoEncoderObject(videoEncoder);
226     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video encoder create by name failed");
227 
228     return object;
229 }
230 
OH_VideoEncoder_Destroy(struct OH_AVCodec * codec)231 OH_AVErrCode OH_VideoEncoder_Destroy(struct OH_AVCodec *codec)
232 {
233     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
234     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER,
235         AV_ERR_INVALID_VAL, "Codec magic error!");
236 
237     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
238 
239     if (videoEncObj != nullptr && videoEncObj->videoEncoder_ != nullptr) {
240         if (videoEncObj->callback_ != nullptr) {
241             videoEncObj->callback_->StopCallback();
242         }
243         {
244             std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
245             videoEncObj->memoryObjList_.clear();
246         }
247         videoEncObj->isStop_.store(true);
248         int32_t ret = videoEncObj->videoEncoder_->Release();
249         if (ret != AVCS_ERR_OK) {
250             AVCODEC_LOGE("Video encoder destroy failed!");
251             delete codec;
252             return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
253         }
254     } else {
255         AVCODEC_LOGD("Video encoder is nullptr!");
256     }
257 
258     delete codec;
259     return AV_ERR_OK;
260 }
261 
OH_VideoEncoder_Configure(struct OH_AVCodec * codec,struct OH_AVFormat * format)262 OH_AVErrCode OH_VideoEncoder_Configure(struct OH_AVCodec *codec, struct OH_AVFormat *format)
263 {
264     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
265     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
266         "Codec magic error!");
267     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
268     CHECK_AND_RETURN_RET_LOG(format->magic_ == AVMagic::AVCODEC_MAGIC_FORMAT, AV_ERR_INVALID_VAL,
269         "Format magic error!");
270 
271     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
272     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
273 
274     int32_t ret = videoEncObj->videoEncoder_->Configure(format->format_);
275     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
276                              "Video encoder configure failed!");
277 
278     return AV_ERR_OK;
279 }
280 
OH_VideoEncoder_Prepare(struct OH_AVCodec * codec)281 OH_AVErrCode OH_VideoEncoder_Prepare(struct OH_AVCodec *codec)
282 {
283     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
284     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
285         "Codec magic error!");
286 
287     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
288     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
289 
290     int32_t ret = videoEncObj->videoEncoder_->Prepare();
291     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
292                              "Video encoder prepare failed!");
293 
294     return AV_ERR_OK;
295 }
296 
OH_VideoEncoder_Start(struct OH_AVCodec * codec)297 OH_AVErrCode OH_VideoEncoder_Start(struct OH_AVCodec *codec)
298 {
299     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
300     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
301         "Codec magic error!");
302 
303     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
304     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
305 
306     videoEncObj->isStop_.store(false);
307     videoEncObj->isEOS_.store(false);
308     videoEncObj->isFlushed_.store(false);
309     int32_t ret = videoEncObj->videoEncoder_->Start();
310     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
311                              "Video encoder start failed!");
312 
313     return AV_ERR_OK;
314 }
315 
OH_VideoEncoder_Stop(struct OH_AVCodec * codec)316 OH_AVErrCode OH_VideoEncoder_Stop(struct OH_AVCodec *codec)
317 {
318     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
319     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
320         "Codec magic error!");
321 
322     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
323     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
324 
325     videoEncObj->isStop_.store(true);
326     int32_t ret = videoEncObj->videoEncoder_->Stop();
327     if (ret != AVCS_ERR_OK) {
328         videoEncObj->isStop_.store(false);
329         AVCODEC_LOGE("Video encoder stop failed");
330         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
331     }
332     std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
333     videoEncObj->memoryObjList_.clear();
334 
335     return AV_ERR_OK;
336 }
337 
OH_VideoEncoder_Flush(struct OH_AVCodec * codec)338 OH_AVErrCode OH_VideoEncoder_Flush(struct OH_AVCodec *codec)
339 {
340     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
341     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
342         "Codec magic error!");
343 
344     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
345     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
346 
347     videoEncObj->isFlushing_.store(true);
348     int32_t ret = videoEncObj->videoEncoder_->Flush();
349     videoEncObj->isFlushed_.store(true);
350     videoEncObj->isFlushing_.store(false);
351     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
352                              "Video encoder flush failed!");
353     std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
354     videoEncObj->memoryObjList_.clear();
355 
356     return AV_ERR_OK;
357 }
358 
OH_VideoEncoder_Reset(struct OH_AVCodec * codec)359 OH_AVErrCode OH_VideoEncoder_Reset(struct OH_AVCodec *codec)
360 {
361     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
362     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
363         "Codec magic error!");
364 
365     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
366     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
367 
368     videoEncObj->isStop_.store(true);
369     int32_t ret = videoEncObj->videoEncoder_->Reset();
370     if (ret != AVCS_ERR_OK) {
371         videoEncObj->isStop_.store(false);
372         AVCODEC_LOGE("Video encoder reset failed");
373         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
374     }
375     std::lock_guard<std::shared_mutex> lock(videoEncObj->memoryObjListMutex_);
376     videoEncObj->memoryObjList_.clear();
377 
378     return AV_ERR_OK;
379 }
380 
OH_VideoEncoder_GetSurface(OH_AVCodec * codec,OHNativeWindow ** window)381 OH_AVErrCode OH_VideoEncoder_GetSurface(OH_AVCodec *codec, OHNativeWindow **window)
382 {
383     CHECK_AND_RETURN_RET_LOG(codec != nullptr && window != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
384     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
385         "Codec magic error!");
386 
387     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
388     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
389 
390     OHOS::sptr<OHOS::Surface> surface = videoEncObj->videoEncoder_->CreateInputSurface();
391     CHECK_AND_RETURN_RET_LOG(surface != nullptr, AV_ERR_OPERATE_NOT_PERMIT,
392                              "Video encoder get surface failed!");
393 
394     *window = CreateNativeWindowFromSurface(&surface);
395     CHECK_AND_RETURN_RET_LOG(*window != nullptr, AV_ERR_INVALID_VAL, "Video encoder get surface failed!");
396     videoEncObj->isInputSurfaceMode_ = true;
397 
398     return AV_ERR_OK;
399 }
400 
OH_VideoEncoder_GetOutputDescription(struct OH_AVCodec * codec)401 OH_AVFormat *OH_VideoEncoder_GetOutputDescription(struct OH_AVCodec *codec)
402 {
403     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
404     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr,
405         "Codec magic error!");
406 
407     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
408     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video encoder is nullptr!");
409 
410     Format format;
411     int32_t ret = videoEncObj->videoEncoder_->GetOutputFormat(format);
412     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video encoder get output description failed!");
413 
414     OH_AVFormat *avFormat = OH_AVFormat_Create();
415     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video encoder get output description failed!");
416     avFormat->format_ = format;
417 
418     return avFormat;
419 }
420 
OH_VideoEncoder_FreeOutputData(struct OH_AVCodec * codec,uint32_t index)421 OH_AVErrCode OH_VideoEncoder_FreeOutputData(struct OH_AVCodec *codec, uint32_t index)
422 {
423     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
424     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
425         "Codec magic error!");
426 
427     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
428     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
429 
430     int32_t ret = videoEncObj->videoEncoder_->ReleaseOutputBuffer(index);
431     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
432         "Video encoder free output data failed!");
433 
434     return AV_ERR_OK;
435 }
436 
OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec * codec)437 OH_AVErrCode OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec *codec)
438 {
439     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
440     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
441         "Codec magic error!");
442 
443     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
444     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
445 
446     int32_t ret = videoEncObj->videoEncoder_->NotifyEos();
447     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
448                              "Video encoder notify end of stream failed!");
449 
450     return AV_ERR_OK;
451 }
452 
OH_VideoEncoder_SetParameter(struct OH_AVCodec * codec,struct OH_AVFormat * format)453 OH_AVErrCode OH_VideoEncoder_SetParameter(struct OH_AVCodec *codec, struct OH_AVFormat *format)
454 {
455     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
456     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
457         "Codec magic error!");
458     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
459     CHECK_AND_RETURN_RET_LOG(format->magic_ == AVMagic::AVCODEC_MAGIC_FORMAT, AV_ERR_INVALID_VAL,
460                              "Format magic error!");
461 
462     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
463     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
464 
465     int32_t ret = videoEncObj->videoEncoder_->SetParameter(format->format_);
466     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
467                              "Video encoder set parameter failed!");
468 
469     return AV_ERR_OK;
470 }
471 
OH_VideoEncoder_SetCallback(struct OH_AVCodec * codec,struct OH_AVCodecAsyncCallback callback,void * userData)472 OH_AVErrCode OH_VideoEncoder_SetCallback(
473     struct OH_AVCodec *codec, struct OH_AVCodecAsyncCallback callback, void *userData)
474 {
475     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
476     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
477         "Codec magic error!");
478 
479     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
480     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
481 
482     videoEncObj->callback_ = std::make_shared<NativeVideoEncoderCallback>(codec, callback, userData);
483 
484     int32_t ret = videoEncObj->videoEncoder_->SetCallback(videoEncObj->callback_);
485     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
486                              "Video encoder set callback failed!");
487 
488     return AV_ERR_OK;
489 }
490 
OH_VideoEncoder_PushInputData(struct OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)491 OH_AVErrCode OH_VideoEncoder_PushInputData(struct OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
492 {
493     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
494     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
495         "Codec magic error!");
496     CHECK_AND_RETURN_RET_LOG(attr.size >= 0, AV_ERR_INVALID_VAL, "Invalid buffer size!");
497 
498     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
499     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, AV_ERR_INVALID_VAL, "Video encoder is nullptr!");
500 
501     if (attr.flags != AVCODEC_BUFFER_FLAGS_CODEC_DATA) {
502         if (videoEncObj->isFirstFrameIn_) {
503             AVCodecTrace::TraceBegin("OH::FirstFrame", attr.pts);
504             videoEncObj->isFirstFrameIn_ = false;
505         } else {
506             AVCodecTrace::TraceBegin("OH::Frame", attr.pts);
507         }
508     }
509 
510     struct AVCodecBufferInfo bufferInfo;
511     bufferInfo.presentationTimeUs = attr.pts;
512     bufferInfo.size = attr.size;
513     bufferInfo.offset = attr.offset;
514     enum AVCodecBufferFlag bufferFlag = static_cast<enum AVCodecBufferFlag>(attr.flags);
515 
516     int32_t ret = videoEncObj->videoEncoder_->QueueInputBuffer(index, bufferInfo, bufferFlag);
517     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
518                              "Video encoder push input data failed!");
519     if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
520         videoEncObj->isEOS_.store(true);
521     }
522 
523     return AV_ERR_OK;
524 }
525 
OH_VideoEncoder_GetInputDescription(OH_AVCodec * codec)526 OH_AVFormat *OH_VideoEncoder_GetInputDescription(OH_AVCodec *codec)
527 {
528     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
529     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, nullptr,
530         "Codec magic error!");
531 
532     struct VideoEncoderObject *videoEncObj = reinterpret_cast<VideoEncoderObject *>(codec);
533     CHECK_AND_RETURN_RET_LOG(videoEncObj->videoEncoder_ != nullptr, nullptr, "Video encoder is nullptr!");
534 
535     Format format;
536     int32_t ret = videoEncObj->videoEncoder_->GetInputFormat(format);
537     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video encoder get input description failed!");
538 
539     OH_AVFormat *avFormat = OH_AVFormat_Create();
540     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video encoder get input description failed!");
541     avFormat->format_ = format;
542 
543     return avFormat;
544 }
545 
OH_VideoEncoder_IsValid(OH_AVCodec * codec,bool * isValid)546 OH_AVErrCode OH_VideoEncoder_IsValid(OH_AVCodec *codec, bool *isValid)
547 {
548     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
549     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_ENCODER, AV_ERR_INVALID_VAL,
550         "Codec magic error!");
551     CHECK_AND_RETURN_RET_LOG(isValid != nullptr, AV_ERR_INVALID_VAL, "Input isValid is nullptr!");
552     *isValid = true;
553     return AV_ERR_OK;
554 }