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