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