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 }