1 /*
2 * Copyright (C) 2025 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 <iostream>
17 #include <set>
18 #include <thread>
19 #include <malloc.h>
20 #include "syspara/parameters.h"
21 #include "securec.h"
22 #include "avcodec_trace.h"
23 #include "avcodec_log.h"
24 #include "utils.h"
25 #include "avcodec_codec_name.h"
26 #include "avc_encoder_util.h"
27 #include "avc_encoder_convert.h"
28 #include "avc_encoder.h"
29
30 namespace OHOS {
31 namespace MediaAVCodec {
32 namespace Codec {
33 namespace {
34 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "AvcEncoder"};
35 constexpr uint32_t INDEX_INPUT = 0;
36 constexpr uint32_t INDEX_OUTPUT = 1;
37 constexpr uint32_t DEFAULT_IN_BUFFER_CNT = 4;
38 constexpr uint32_t DEFAULT_OUT_BUFFER_CNT = 4;
39 constexpr uint32_t DEFAULT_MIN_BUFFER_CNT = 2;
40 constexpr int32_t VIDEO_MIN_BUFFER_SIZE = 1474560;
41 constexpr int32_t VIDEO_MIN_SIZE = 16;
42 constexpr int32_t VIDEO_ALIGNMENT_SIZE = 2;
43 constexpr int32_t VIDEO_MAX_WIDTH_SIZE = 2560;
44 constexpr int32_t VIDEO_MAX_HEIGHT_SIZE = 2560;
45 constexpr int32_t DEFAULT_VIDEO_WIDTH = 1920;
46 constexpr int32_t DEFAULT_VIDEO_HEIGHT = 1080;
47 constexpr uint32_t DEFAULT_TRY_ENCODE_TIME = 100;
48 constexpr uint32_t DEFAULT_ENCODE_WAIT_TIME = 200;
49 constexpr int32_t VIDEO_INSTANCE_SIZE = 16;
50 constexpr int32_t VIDEO_BITRATE_MIN_SIZE = 1;
51 constexpr int32_t VIDEO_BITRATE_MAX_SIZE = 240000000;
52 constexpr int32_t VIDEO_FRAMERATE_MIN_SIZE = 1;
53 constexpr int32_t VIDEO_FRAMERATE_MAX_SIZE = 120;
54 constexpr int32_t VIDEO_BLOCKPERFRAME_SIZE = 36864;
55 constexpr int32_t VIDEO_BLOCKPERSEC_SIZE = 983040;
56 constexpr int32_t VIDEO_QUALITY_MAX = 100;
57 constexpr int32_t VIDEO_QUALITY_MIN = 0;
58 constexpr int32_t TIME_SEC_TO_MS = 1000;
59 constexpr int32_t VIDEO_QP_MAX = 51;
60 constexpr int32_t VIDEO_QP_MIN = 4;
61 constexpr int32_t VIDEO_QP_DEFAULT = 20;
62 constexpr int32_t VIDEO_IFRAME_INTERVAL_MIN_TIME = 1000;
63 constexpr int32_t VIDEO_IFRAME_INTERVAL_MAX_TIME = 3600000;
64 constexpr int32_t DEFAULT_VIDEO_INTERVAL_TIME = 2000;
65 constexpr int32_t DEFAULT_VIDEO_IFRAME_INTERVAL = 60;
66 constexpr int32_t DEFAULT_VIDEO_BITRATE = 6000000;
67 constexpr double DEFAULT_VIDEO_FRAMERATE = 30.0;
68
69 constexpr struct {
70 const std::string_view codecName;
71 const std::string_view mimeType;
72 const char *codecStr;
73 const bool isEncoder;
74 } SUPPORT_VCODEC[] = {
75 {AVCodecCodecName::VIDEO_ENCODER_AVC_NAME, CodecMimeType::VIDEO_AVC, "h264", true},
76 };
77 constexpr uint32_t SUPPORT_VCODEC_NUM = sizeof(SUPPORT_VCODEC) / sizeof(SUPPORT_VCODEC[0]);
78 } // namespace
79
80 const char *AVC_ENC_LIB_PATH = "libavcenc_ohos.z.so";
81 const char *AVC_ENC_CREATE_FUNC_NAME = "InitEncoder";
82 const char *AVC_ENC_ENCODE_FRAME_FUNC_NAME = "EncodeProcess";
83 const char *AVC_ENC_DELETE_FUNC_NAME = "ReleaseEncoder";
84
85 using namespace OHOS::Media;
86
AvcEncLog(uint32_t channelId,IHW264VIDEO_ALG_LOG_LEVEL eLevel,uint8_t * pMsg,...)87 void AvcEncLog(uint32_t channelId, IHW264VIDEO_ALG_LOG_LEVEL eLevel, uint8_t *pMsg, ...)
88 {
89 va_list args;
90 int32_t maxSize = 1024; // 1024 max size of one log
91 std::vector<char> buf(maxSize);
92 va_start(args, reinterpret_cast<const char*>(pMsg));
93 int32_t size = vsnprintf_s(buf.data(), buf.size(), buf.size()-1, reinterpret_cast<const char*>(pMsg), args);
94 va_end(args);
95 if (size >= maxSize) {
96 size = maxSize - 1;
97 }
98
99 auto msg = std::string(buf.data(), size);
100
101 if (eLevel >= IHW264VIDEO_ALG_LOG_DEBUG) {
102 switch (eLevel) {
103 case IHW264VIDEO_ALG_LOG_ERROR: {
104 AVCODEC_LOGE("%{public}s", msg.c_str());
105 break;
106 }
107 case IHW264VIDEO_ALG_LOG_WARNING: {
108 AVCODEC_LOGW("%{public}s", msg.c_str());
109 break;
110 }
111 case IHW264VIDEO_ALG_LOG_INFO: {
112 AVCODEC_LOGI("%{public}s", msg.c_str());
113 break;
114 }
115 case IHW264VIDEO_ALG_LOG_DEBUG: {
116 AVCODEC_LOGD("%{public}s", msg.c_str());
117 break;
118 }
119 default: {
120 AVCODEC_LOGI("%{public}s", msg.c_str());
121 break;
122 }
123 }
124 }
125 return;
126 }
127
AvcEncoder(const std::string & name)128 AvcEncoder::AvcEncoder(const std::string &name)
129 : codecName_(name),
130 state_(State::UNINITIALIZED),
131 encWidth_(DEFAULT_VIDEO_WIDTH),
132 encHeight_(DEFAULT_VIDEO_HEIGHT),
133 encBitrate_(0),
134 encQp_(VIDEO_QP_DEFAULT),
135 encQpMax_(VIDEO_QP_MAX),
136 encQpMin_(VIDEO_QP_MIN),
137 encIperiod_(DEFAULT_VIDEO_IFRAME_INTERVAL),
138 encFrameRate_(DEFAULT_VIDEO_FRAMERATE)
139 {
140 AVCODEC_SYNC_TRACE;
141 std::unique_lock<std::mutex> lock(encoderCountMutex_);
142 if (!freeIDSet_.empty()) {
143 encInstanceID_ = freeIDSet_[0];
144 freeIDSet_.erase(freeIDSet_.begin());
145 encInstanceIDSet_.push_back(encInstanceID_);
146 } else if (freeIDSet_.size() + encInstanceIDSet_.size() < VIDEO_INSTANCE_SIZE) {
147 encInstanceID_ = freeIDSet_.size() + encInstanceIDSet_.size();
148 encInstanceIDSet_.push_back(encInstanceID_);
149 } else {
150 encInstanceID_ = VIDEO_INSTANCE_SIZE + 1;
151 }
152 lock.unlock();
153
154 if (encInstanceID_ < VIDEO_INSTANCE_SIZE) {
155 handle_ = dlopen(AVC_ENC_LIB_PATH, RTLD_LAZY);
156 if (handle_ == nullptr) {
157 AVCODEC_LOGE("Load avc codec failed: %{public}s", AVC_ENC_LIB_PATH);
158 }
159 AvcFuncMatch();
160 AVCODEC_LOGI("Num %{public}u AvcEncoder entered, state: Uninitialized", encInstanceID_);
161 } else {
162 AVCODEC_LOGE("AvcEncoder already has %{public}d instances, cannot has more instances", VIDEO_INSTANCE_SIZE);
163 state_ = State::ERROR;
164 }
165 InitAvcEncoderParams();
166 }
167
~AvcEncoder()168 AvcEncoder::~AvcEncoder()
169 {
170 ReleaseResource();
171 ReleaseHandle();
172 callback_ = nullptr;
173 if (encInstanceID_ < VIDEO_INSTANCE_SIZE) {
174 std::lock_guard<std::mutex> lock(encoderCountMutex_);
175 freeIDSet_.push_back(encInstanceID_);
176 auto it = std::find(encInstanceIDSet_.begin(), encInstanceIDSet_.end(), encInstanceID_);
177 if (it != encInstanceIDSet_.end()) {
178 encInstanceIDSet_.erase(it);
179 }
180 }
181 }
182
AvcFuncMatch()183 void AvcEncoder::AvcFuncMatch()
184 {
185 if (handle_ != nullptr) {
186 avcEncoderCreateFunc_ = reinterpret_cast<CreateAvcEncoderFuncType>(dlsym(handle_,
187 AVC_ENC_CREATE_FUNC_NAME));
188 avcEncoderFrameFunc_ = reinterpret_cast<EncodeFuncType>(dlsym(handle_,
189 AVC_ENC_ENCODE_FRAME_FUNC_NAME));
190 avcEncoderDeleteFunc_ = reinterpret_cast<DeleteFuncType>(dlsym(handle_,
191 AVC_ENC_DELETE_FUNC_NAME));
192 if (avcEncoderCreateFunc_ == nullptr ||
193 avcEncoderFrameFunc_ == nullptr ||
194 avcEncoderDeleteFunc_ == nullptr) {
195 AVCODEC_LOGE("AvcEncoder avcFuncMatch_ failed!");
196 ReleaseHandle();
197 }
198 }
199 }
200
ReleaseHandle()201 void AvcEncoder::ReleaseHandle()
202 {
203 std::unique_lock<std::mutex> runLock(encRunMutex_);
204 avcEncoderCreateFunc_ = nullptr;
205 avcEncoderFrameFunc_ = nullptr;
206 avcEncoderDeleteFunc_ = nullptr;
207 if (handle_ != nullptr) {
208 dlclose(handle_);
209 handle_ = nullptr;
210 }
211 runLock.unlock();
212 }
213
ReleaseSurfaceBuffer()214 void AvcEncoder::ReleaseSurfaceBuffer()
215 {
216 sptr<SurfaceBuffer> buffer;
217 sptr<SyncFence> fence;
218 int64_t pts = -1;
219 OHOS::Rect damage;
220 GSError ret = inputSurface_->AcquireBuffer(buffer, fence, pts, damage);
221 if (ret != GSERROR_OK || buffer == nullptr) {
222 return;
223 }
224 AVCODEC_LOGW("release buffer to surface, seq: %{public}u, pts: %" PRId64 "", buffer->GetSeqNum(), pts);
225 inputSurface_->ReleaseBuffer(buffer, -1);
226 }
227
ClearDirtyList()228 void AvcEncoder::ClearDirtyList()
229 {
230 sptr<SurfaceBuffer> buffer;
231 sptr<SyncFence> fence;
232 int64_t pts = -1;
233 OHOS::Rect damage;
234 while (true) {
235 GSError ret = inputSurface_->AcquireBuffer(buffer, fence, pts, damage);
236 if (ret != GSERROR_OK || buffer == nullptr) {
237 return;
238 }
239 AVCODEC_LOGI("release surface buffer, seq: %{public}u, pts: %{public}" PRId64 "", buffer->GetSeqNum(), pts);
240 inputSurface_->ReleaseBuffer(buffer, -1);
241 }
242 }
243
WaitForInBuffer()244 void AvcEncoder::WaitForInBuffer()
245 {
246 std::unique_lock<std::mutex> listLock(freeListMutex_);
247 surfaceRecvCv_.wait(listLock, [this] {
248 if (state_ == State::STOPPING) {
249 return true;
250 }
251
252 if (!freeList_.empty()) {
253 return true;
254 }
255
256 return false;
257 });
258 }
259
GetBufferFromSurface()260 void AvcEncoder::GetBufferFromSurface()
261 {
262 CHECK_AND_RETURN_LOG(inputSurface_ != nullptr, "inputSurface_ not exists");
263 if (freeList_.empty()) {
264 WaitForInBuffer();
265 }
266 if (state_ == State::STOPPING) {
267 ReleaseSurfaceBuffer();
268 AVCODEC_LOGE("surface exit .");
269 return;
270 }
271
272 sptr<SurfaceBuffer> buffer = nullptr;
273 sptr<SyncFence> fence = nullptr;
274 OHOS::Rect damage;
275 int64_t pts = -1;
276 GSError ret = inputSurface_->AcquireBuffer(buffer, fence, pts, damage);
277 if (ret != GSERROR_OK || buffer == nullptr) {
278 return;
279 }
280 constexpr uint32_t waitForEver = -1;
281 (void)fence->Wait(waitForEver);
282 if (state_ == State::STOPPING) {
283 inputSurface_->ReleaseBuffer(buffer, -1);
284 return;
285 }
286 AVCODEC_LOGD("timestamp: %{public}" PRId64 ", dataSize: %{public}d", pts, buffer->GetSize());
287
288 CHECK_AND_RETURN_LOG(!freeList_.empty(), "freeList_ is empty!");
289 std::unique_lock<std::mutex> listLock(freeListMutex_);
290 uint32_t index = freeList_.front();
291 freeList_.pop_front();
292 listLock.unlock();
293 std::shared_ptr<FBuffer> &inputBuffer = buffers_[INDEX_INPUT][index];
294
295 CHECK_AND_RETURN_LOG(inputBuffer != nullptr, "input buffer is null");
296 if (enableSurfaceModeInputCb_) {
297 inputBuffer->surfaceBuffer_ = buffer;
298 inputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer();
299 CHECK_AND_RETURN_LOG(inputBuffer->avBuffer_ != nullptr, "Allocate input buffer failed!");
300 inputBuffer->avBuffer_->pts_ = pts;
301 callback_->OnInputBufferAvailable(index, inputBuffer->avBuffer_);
302 } else {
303 inputBuffer->surfaceBuffer_ = nullptr;
304 inputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer(buffer);
305 CHECK_AND_RETURN_LOG(inputBuffer->avBuffer_ != nullptr, "Allocate input buffer failed!");
306 inputBuffer->avBuffer_->pts_ = pts;
307 inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
308 inputAvailQue_->Push(index);
309 }
310 }
311
OnBufferAvailable()312 void AvcEncoder::EncoderBuffersConsumerListener::OnBufferAvailable()
313 {
314 if (codec_) {
315 codec_->GetBufferFromSurface();
316 }
317 }
318
CreateInputSurface()319 sptr<Surface> AvcEncoder::CreateInputSurface()
320 {
321 if (inputSurface_) {
322 AVCODEC_LOGE("inputSurface_ already exists");
323 return nullptr;
324 }
325
326 sptr<Surface> consumerSurface = Surface::CreateSurfaceAsConsumer("HEncoderSurface");
327 if (consumerSurface == nullptr) {
328 AVCODEC_LOGE("Create the surface consummer fail");
329 return nullptr;
330 }
331 GSError err = consumerSurface->SetDefaultUsage(SURFACE_MODE_CONSUMER_USAGE);
332 if (err == GSERROR_OK) {
333 AVCODEC_LOGI("set consumer usage 0x%{public}x succ", SURFACE_MODE_CONSUMER_USAGE);
334 } else {
335 AVCODEC_LOGW("set consumer usage 0x%{public}x failed", SURFACE_MODE_CONSUMER_USAGE);
336 }
337
338 sptr<IBufferProducer> producer = consumerSurface->GetProducer();
339 if (producer == nullptr) {
340 AVCODEC_LOGE("Get the surface producer fail");
341 return nullptr;
342 }
343
344 sptr<Surface> producerSurface = Surface::CreateSurfaceAsProducer(producer);
345 if (producerSurface == nullptr) {
346 AVCODEC_LOGE("CreateSurfaceAsProducer fail");
347 return nullptr;
348 }
349
350 inputSurface_ = consumerSurface;
351 if (DEFAULT_IN_BUFFER_CNT > inputSurface_->GetQueueSize()) {
352 inputSurface_->SetQueueSize(DEFAULT_IN_BUFFER_CNT);
353 }
354 AVCODEC_LOGI("succ, surface id = %" PRIu64 ", queue size %u",
355 inputSurface_->GetUniqueId(), inputSurface_->GetQueueSize());
356 return producerSurface;
357 }
358
SetInputSurface(sptr<Surface> surface)359 int32_t AvcEncoder::SetInputSurface(sptr<Surface> surface)
360 {
361 if (inputSurface_) {
362 AVCODEC_LOGW("inputSurface_ already exists");
363 }
364
365 if (surface == nullptr) {
366 AVCODEC_LOGE("surface is null");
367 return AVCS_ERR_INVALID_VAL;
368 }
369 if (!surface->IsConsumer()) {
370 AVCODEC_LOGE("expect consumer surface");
371 return AVCS_ERR_INVALID_VAL;
372 }
373
374 inputSurface_ = surface;
375 if (DEFAULT_IN_BUFFER_CNT > inputSurface_->GetQueueSize()) {
376 inputSurface_->SetQueueSize(DEFAULT_IN_BUFFER_CNT);
377 }
378 AVCODEC_LOGI("succ");
379 return AVCS_ERR_OK;
380 }
381
Initialize()382 int32_t AvcEncoder::Initialize()
383 {
384 AVCODEC_SYNC_TRACE;
385 std::string codecName;
386 std::string_view mime;
387 for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
388 if (SUPPORT_VCODEC[i].codecName == codecName_) {
389 codecName = SUPPORT_VCODEC[i].codecStr;
390 mime = SUPPORT_VCODEC[i].mimeType;
391 break;
392 }
393 }
394 CHECK_AND_RETURN_RET_LOG(!codecName.empty(), AVCS_ERR_INVALID_VAL,
395 "Init codec failed: not support name: %{public}s", codecName_.c_str());
396 format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, mime);
397 format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, codecName_);
398
399 sendTask_ = std::make_shared<TaskThread>("SendFrame");
400 sendTask_->RegisterHandler([this] { SendFrame(); });
401 state_ = State::INITIALIZED;
402 isFirstFrame_ = true;
403 AVCODEC_LOGI("Init codec successful, state: Uninitialized -> Initialized");
404 return AVCS_ERR_OK;
405 }
406
ConfigureDefaultVal(const Format & format,const std::string_view & formatKey,int32_t minVal,int32_t maxVal)407 void AvcEncoder::ConfigureDefaultVal(const Format &format, const std::string_view &formatKey,
408 int32_t minVal, int32_t maxVal)
409 {
410 int32_t val32 = 0;
411 if (format.GetIntValue(formatKey, val32) && val32 >= minVal && val32 <= maxVal) {
412 format_.PutIntValue(formatKey, val32);
413 } else {
414 AVCODEC_LOGW("Set parameter failed: %{public}s, which minimum threshold=%{public}d, "
415 "maximum threshold=%{public}d",
416 std::string(formatKey).c_str(), minVal, maxVal);
417 }
418 }
419
Configure(const Format & format)420 int32_t AvcEncoder::Configure(const Format &format)
421 {
422 AVCODEC_SYNC_TRACE;
423 if (state_ == State::UNINITIALIZED) {
424 int32_t ret = Initialize();
425 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Init codec failed");
426 }
427 CHECK_AND_RETURN_RET_LOG((state_ == State::INITIALIZED), AVCS_ERR_INVALID_STATE,
428 "Configure codec failed: not in Initialized state");
429
430 format_.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_VIDEO_WIDTH);
431 format_.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_VIDEO_HEIGHT);
432 format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, DEFAULT_OUT_BUFFER_CNT);
433 format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, DEFAULT_IN_BUFFER_CNT);
434 for (auto &it : format.GetFormatMap()) {
435 if (it.first == MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT) {
436 ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
437 } else if (it.first == MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT) {
438 ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
439 } else if (it.first == MediaDescriptionKey::MD_KEY_WIDTH) {
440 ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_WIDTH_SIZE);
441 } else if (it.first == MediaDescriptionKey::MD_KEY_HEIGHT) {
442 ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_HEIGHT_SIZE);
443 } else if (it.first == MediaDescriptionKey::MD_KEY_I_FRAME_INTERVAL) {
444 ConfigureDefaultVal(format, it.first);
445 } else if (it.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
446 ConfigureDefaultVal(format, it.first);
447 } else if (it.first == MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE) {
448 ConfigureDefaultVal(format, it.first);
449 } else if (it.first == OHOS::Media::Tag::VIDEO_ENCODER_ENABLE_SURFACE_INPUT_CALLBACK) {
450 ConfigureDefaultVal(format, it.first);
451 } else if (it.first == MediaDescriptionKey::MD_KEY_BITRATE) {
452 int64_t val64 = 0;
453 format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64);
454 format_.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64);
455 } else if (it.first == MediaDescriptionKey::MD_KEY_FRAME_RATE) {
456 double val = 0;
457 format.GetDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val);
458 format_.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val);
459 } else {
460 AVCODEC_LOGW("Set parameter need check: size:%{public}s,", it.first.data());
461 }
462 }
463 int32_t ret = ConfigureContext(format);
464 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "config error");
465 state_ = State::CONFIGURED;
466 AVCODEC_LOGI("Configured codec successful, state: Initialized -> Configured");
467 return AVCS_ERR_OK;
468 }
469
ConfigureContext(const Format & format)470 int32_t AvcEncoder::ConfigureContext(const Format &format)
471 {
472 GetBitRateFromUser(format);
473 GetFrameRateFromUser(format);
474 GetBitRateModeFromUser(format);
475 GetIFrameIntervalFromUser(format);
476 GetRequestIDRFromUser(format);
477 GetQpRangeFromUser(format);
478 GetColorAspects(format);
479 CheckIfEnableCb(format);
480 int32_t ret = SetupPort(format);
481 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_VAL, "config format error");
482 return AVCS_ERR_OK;
483 }
484
GetQpRangeFromUser(const Format & format)485 void AvcEncoder::GetQpRangeFromUser(const Format &format)
486 {
487 int32_t minQp;
488 int32_t maxQp;
489 if (!format.GetIntValue(OHOS::Media::Tag::VIDEO_ENCODER_QP_MIN, minQp) ||
490 !format.GetIntValue(OHOS::Media::Tag::VIDEO_ENCODER_QP_MAX, maxQp)) {
491 AVCODEC_LOGE("user set qp range default");
492 return;
493 }
494
495 encQpMin_ = minQp;
496 encQpMax_ = maxQp;
497 AVCODEC_LOGI("user set qp min %{public}d, max %{public}d", encQpMin_, encQpMax_);
498 return;
499 }
500
GetBitRateFromUser(const Format & format)501 void AvcEncoder::GetBitRateFromUser(const Format &format)
502 {
503 int64_t bitRateLong;
504 if (format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, bitRateLong) && bitRateLong > 0 &&
505 bitRateLong <= UINT32_MAX) {
506 AVCODEC_LOGI("user set bitrate %{public}" PRId64 "", bitRateLong);
507 encBitrate_ = static_cast<int32_t>(bitRateLong);
508 CheckBitRateSupport(encBitrate_);
509 return;
510 }
511 int32_t bitRateInt;
512 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_BITRATE, bitRateInt) && bitRateInt > 0) {
513 AVCODEC_LOGI("user set bitrate %{public}d", bitRateInt);
514 encBitrate_ = bitRateInt;
515 CheckBitRateSupport(encBitrate_);
516 return;
517 }
518 return;
519 }
520
GetPixelFmtFromUser(const Format & format)521 bool AvcEncoder::GetPixelFmtFromUser(const Format &format)
522 {
523 VideoPixelFormat innerFmt;
524 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, *(int *)&innerFmt) &&
525 innerFmt != VideoPixelFormat::SURFACE_FORMAT) {
526 srcPixelFmt_ = innerFmt;
527 AVCODEC_LOGI("configuread pixel fmt %{public}d", static_cast<int32_t>(innerFmt));
528 } else {
529 AVCODEC_LOGI("user don't set pixel fmt, use default nv21");
530 }
531 return true;
532 }
533
GetFrameRateFromUser(const Format & format)534 void AvcEncoder::GetFrameRateFromUser(const Format &format)
535 {
536 double frameRateDouble;
537 if (format.GetDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, frameRateDouble) && frameRateDouble > 0) {
538 AVCODEC_LOGI("user set frame rate %{public}.2f", frameRateDouble);
539 encFrameRate_ = frameRateDouble;
540 CheckFrameRateSupport(encFrameRate_);
541 return;
542 }
543 int frameRateInt;
544 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, frameRateInt) && frameRateInt > 0) {
545 AVCODEC_LOGI("user set frame rate %{public}d", frameRateInt);
546 encFrameRate_ = static_cast<double>(frameRateInt);
547 CheckFrameRateSupport(encFrameRate_);
548 return;
549 }
550 encFrameRate_ = DEFAULT_VIDEO_FRAMERATE; // default frame rate 30.0
551 return;
552 }
553
GetBitRateModeFromUser(const Format & format)554 void AvcEncoder::GetBitRateModeFromUser(const Format &format)
555 {
556 VideoEncodeBitrateMode mode;
557 AVCProfile profile;
558 AVCLevel level;
559 int32_t quality;
560 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, *reinterpret_cast<int *>(&mode))) {
561 AVCODEC_LOGI("user set bitrate mod %{public}d", static_cast<int>(mode));
562 bitrateMode_ = mode;
563 if (mode == VideoEncodeBitrateMode::CQ &&
564 format.GetIntValue(MediaDescriptionKey::MD_KEY_QUALITY, quality) && quality >= 0) {
565 avcQuality_ = quality;
566 encQp_ = VIDEO_QP_MIN +
567 (VIDEO_QUALITY_MAX - quality) * ((VIDEO_QP_MAX - VIDEO_QP_MIN) / VIDEO_QUALITY_MAX);
568 AVCODEC_LOGI("user set avc quality %{public}d qp %{public}d", quality, encQp_);
569 }
570 }
571
572 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_PROFILE, *reinterpret_cast<int *>(&profile))) {
573 AVCODEC_LOGI("user set avc profile %{public}d", static_cast<int>(profile));
574 avcProfile_ = profile;
575 }
576
577 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_LEVEL, *reinterpret_cast<int *>(&level))) {
578 AVCODEC_LOGI("user set avc level %{public}d", static_cast<int>(level));
579 avcLevel_ = level;
580 }
581
582 return;
583 }
584
GetIFrameIntervalFromUser(const Format & format)585 void AvcEncoder::GetIFrameIntervalFromUser(const Format &format)
586 {
587 int32_t interval;
588 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_I_FRAME_INTERVAL, interval) && interval > 0) {
589 CheckIFrameIntervalTimeSupport(interval);
590 encIperiod_ = interval * encFrameRate_ / TIME_SEC_TO_MS;
591 AVCODEC_LOGI("user set iframe interval %{public}ds, transfer to %{public}dframes",
592 interval / TIME_SEC_TO_MS, encIperiod_);
593 }
594 return;
595 }
596
GetRequestIDRFromUser(const Format & format)597 void AvcEncoder::GetRequestIDRFromUser(const Format &format)
598 {
599 int32_t requestIdr;
600 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, requestIdr) && requestIdr != 0) {
601 SignalRequestIDRFrame();
602 }
603 return;
604 }
605
GetColorAspects(const Format & format)606 void AvcEncoder::GetColorAspects(const Format &format)
607 {
608 int range = 0;
609 int primary = static_cast<int>(COLOR_PRIMARY_UNSPECIFIED);
610 int transfer = static_cast<int>(TRANSFER_CHARACTERISTIC_UNSPECIFIED);
611 int matrix = static_cast<int>(MATRIX_COEFFICIENT_UNSPECIFIED);
612
613 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_RANGE_FLAG, range)) {
614 AVCODEC_LOGI("user set range flag %{public}d", range);
615 }
616 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_COLOR_PRIMARIES, primary)) {
617 AVCODEC_LOGI("user set primary %{public}d", primary);
618 }
619 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_TRANSFER_CHARACTERISTICS, transfer)) {
620 AVCODEC_LOGI("user set transfer %{public}d", transfer);
621 }
622 if (format.GetIntValue(MediaDescriptionKey::MD_KEY_MATRIX_COEFFICIENTS, matrix)) {
623 AVCODEC_LOGI("user set matrix %{public}d", matrix);
624 }
625 if (primary < 0 || primary > ColorPrimary::COLOR_PRIMARY_P3D65 ||
626 transfer < 0 || transfer > TransferCharacteristic::TRANSFER_CHARACTERISTIC_HLG ||
627 matrix < 0 || matrix > MatrixCoefficient::MATRIX_COEFFICIENT_ICTCP) {
628 AVCODEC_LOGW("user set invalid color");
629 return;
630 }
631
632 srcRange_ = static_cast<uint8_t>(range);
633 srcPrimary_ = static_cast<ColorPrimary>(primary);
634 srcTransfer_ = static_cast<TransferCharacteristic>(transfer);
635 srcMatrix_ = static_cast<MatrixCoefficient>(matrix);
636 return;
637 }
638
CheckIfEnableCb(const Format & format)639 void AvcEncoder::CheckIfEnableCb(const Format &format)
640 {
641 int32_t enableCb = 0;
642 if (format.GetIntValue(OHOS::Media::Tag::VIDEO_ENCODER_ENABLE_SURFACE_INPUT_CALLBACK, enableCb)) {
643 AVCODEC_LOGI("enable surface mode callback flag %{public}d", enableCb);
644 enableSurfaceModeInputCb_ = static_cast<bool>(enableCb);
645 }
646 return;
647 }
648
CheckBitRateSupport(int32_t & bitrate)649 void AvcEncoder::CheckBitRateSupport(int32_t &bitrate)
650 {
651 if (bitrate > VIDEO_BITRATE_MAX_SIZE || bitrate < VIDEO_BITRATE_MIN_SIZE) {
652 AVCODEC_LOGW("bitrate %{public}d not in [%{public}d, %{public}d], set default %{public}d",
653 bitrate, VIDEO_BITRATE_MIN_SIZE, VIDEO_BITRATE_MAX_SIZE, DEFAULT_VIDEO_BITRATE);
654 bitrate = DEFAULT_VIDEO_BITRATE;
655 }
656 return;
657 }
658
CheckFrameRateSupport(double & framerate)659 void AvcEncoder::CheckFrameRateSupport(double &framerate)
660 {
661 if (framerate > VIDEO_FRAMERATE_MAX_SIZE || framerate < VIDEO_FRAMERATE_MIN_SIZE) {
662 AVCODEC_LOGW("framerate %{public}f not in [%{public}d, %{public}d], set default %{public}f",
663 framerate, VIDEO_FRAMERATE_MIN_SIZE, VIDEO_FRAMERATE_MAX_SIZE, DEFAULT_VIDEO_FRAMERATE);
664 framerate = DEFAULT_VIDEO_FRAMERATE;
665 }
666 return;
667 }
668
CheckIFrameIntervalTimeSupport(int32_t & interval)669 void AvcEncoder::CheckIFrameIntervalTimeSupport(int32_t &interval)
670 {
671 if (interval > VIDEO_IFRAME_INTERVAL_MAX_TIME || interval < VIDEO_IFRAME_INTERVAL_MIN_TIME) {
672 AVCODEC_LOGW("interval %{public}d not in [%{public}d, %{public}d], set default %{public}d",
673 interval, VIDEO_IFRAME_INTERVAL_MIN_TIME, VIDEO_IFRAME_INTERVAL_MAX_TIME,
674 DEFAULT_VIDEO_INTERVAL_TIME);
675 interval = DEFAULT_VIDEO_INTERVAL_TIME;
676 }
677 return;
678 }
679
SetupPort(const Format & format)680 int32_t AvcEncoder::SetupPort(const Format &format)
681 {
682 int32_t width;
683 if (!format.GetIntValue(MediaDescriptionKey::MD_KEY_WIDTH, width) ||
684 width <= 0 || width > VIDEO_MAX_WIDTH_SIZE) {
685 AVCODEC_LOGE("format should contain width");
686 return AVCS_ERR_INVALID_VAL;
687 }
688 int32_t height;
689 if (!format.GetIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, height) ||
690 height <= 0 || height > VIDEO_MAX_HEIGHT_SIZE) {
691 AVCODEC_LOGE("format should contain height");
692 return AVCS_ERR_INVALID_VAL;
693 }
694 encWidth_ = width;
695 encHeight_ = height;
696 AVCODEC_LOGI("user set width %{public}d, height %{public}d", width, height);
697 if (!GetPixelFmtFromUser(format)) {
698 return AVCS_ERR_INVALID_VAL;
699 }
700 return AVCS_ERR_OK;
701 }
702
SignalRequestIDRFrame()703 int32_t AvcEncoder::SignalRequestIDRFrame()
704 {
705 AVCODEC_LOGI("request idr frame success");
706 encIdrRequest_ = true;
707 return AVCS_ERR_OK;
708 }
709
InitBuffers()710 void AvcEncoder::InitBuffers()
711 {
712 inputAvailQue_->SetActive(true);
713 codecAvailQue_->SetActive(true);
714 freeList_.clear();
715 for (uint32_t i = 0; i < buffers_[INDEX_INPUT].size(); i++) {
716 buffers_[INDEX_INPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_USER;
717 if (inputSurface_ == nullptr) {
718 callback_->OnInputBufferAvailable(i, buffers_[INDEX_INPUT][i]->avBuffer_);
719 } else {
720 freeList_.emplace_back(i);
721 }
722 AVCODEC_LOGI("OnInputBufferAvailable frame index = %{public}d, owner = %{public}d",
723 i, buffers_[INDEX_INPUT][i]->owner_.load());
724 }
725
726 for (uint32_t i = 0; i < buffers_[INDEX_OUTPUT].size(); i++) {
727 buffers_[INDEX_OUTPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
728 codecAvailQue_->Push(i);
729 }
730 }
731
CalculateBufferSize()732 void AvcEncoder::CalculateBufferSize()
733 {
734 int32_t stride = AlignUp(encWidth_, VIDEO_ALIGN_SIZE);
735 inputBufferSize_ = static_cast<int32_t>(stride * encHeight_ * VIDEO_PIX_DEPTH_RGBA);
736 outputBufferSize_ = std::max(VIDEO_MIN_BUFFER_SIZE, outputBufferSize_);
737 AVCODEC_LOGI("width = %{public}d, height = %{public}d, stride = %{public}d, Input buffer size = %{public}d, output "
738 "buffer size=%{public}d",
739 encWidth_, encHeight_, stride, inputBufferSize_, outputBufferSize_);
740 }
741
AllocateInputBuffer(int32_t bufferCnt,int32_t inBufferSize)742 int32_t AvcEncoder::AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize)
743 {
744 uint32_t valBufferCnt = 0;
745
746 convertBuffer_ = nullptr;
747 std::shared_ptr<AVAllocator> alloc =
748 AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
749 CHECK_AND_RETURN_RET_LOG(alloc != nullptr, AVCS_ERR_NO_MEMORY, "convert buffer allocator is nullptr");
750 convertBuffer_ = AVBuffer::CreateAVBuffer(alloc, inBufferSize);
751 CHECK_AND_RETURN_RET_LOG(convertBuffer_ != nullptr, AVCS_ERR_NO_MEMORY, "Allocate convert buffer failed");
752
753 for (int32_t i = 0; i < bufferCnt; i++) {
754 std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
755 if (inputSurface_ == nullptr) {
756 std::shared_ptr<AVAllocator> allocator =
757 AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
758 CHECK_AND_CONTINUE_LOG(allocator != nullptr, "input buffer %{public}d allocator is nullptr", i);
759 buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, inBufferSize);
760 CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr && buf->avBuffer_->memory_ != nullptr,
761 "Allocate input buffer failed, index=%{public}d", i);
762 AVCODEC_LOGI("Allocate input buffer success: index=%{public}d, size=%{public}d",
763 i, buf->avBuffer_->memory_->GetCapacity());
764 } else {
765 buf->avBuffer_ = nullptr;
766 }
767 buffers_[INDEX_INPUT].emplace_back(buf);
768 valBufferCnt++;
769 }
770 if (valBufferCnt < DEFAULT_MIN_BUFFER_CNT) {
771 AVCODEC_LOGE("Allocate input buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
772 buffers_[INDEX_INPUT].clear();
773 return AVCS_ERR_NO_MEMORY;
774 }
775 return AVCS_ERR_OK;
776 }
777
AllocateOutputBuffer(int32_t bufferCnt,int32_t outBufferSize)778 int32_t AvcEncoder::AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize)
779 {
780 uint32_t valBufferCnt = 0;
781 for (int i = 0; i < bufferCnt; i++) {
782 std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
783 std::shared_ptr<AVAllocator> allocator =
784 AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
785 CHECK_AND_CONTINUE_LOG(allocator != nullptr, "output buffer %{public}d allocator is nullptr", i);
786
787 buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, outBufferSize);
788 CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr && buf->avBuffer_->memory_ != nullptr,
789 "Allocate output buffer failed, index=%{public}d", i);
790 AVCODEC_LOGI("Allocate output share buffer success: index=%{public}d, size=%{public}d",
791 i, buf->avBuffer_->memory_->GetCapacity());
792
793 buf->width_ = encWidth_;
794 buf->height_ = encHeight_;
795 buffers_[INDEX_OUTPUT].emplace_back(buf);
796 valBufferCnt++;
797 }
798 if (valBufferCnt < DEFAULT_MIN_BUFFER_CNT) {
799 AVCODEC_LOGE("Allocate output buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
800 buffers_[INDEX_INPUT].clear();
801 buffers_[INDEX_OUTPUT].clear();
802 return AVCS_ERR_NO_MEMORY;
803 }
804 return AVCS_ERR_OK;
805 }
806
AllocateBuffers()807 int32_t AvcEncoder::AllocateBuffers()
808 {
809 AVCODEC_SYNC_TRACE;
810 CalculateBufferSize();
811 CHECK_AND_RETURN_RET_LOG(inputBufferSize_ > 0 && outputBufferSize_ > 0, AVCS_ERR_INVALID_VAL,
812 "Allocate buffer with input size=%{public}d, output size=%{public}d failed",
813 inputBufferSize_, outputBufferSize_);
814
815 int32_t inputBufferCnt = DEFAULT_IN_BUFFER_CNT;
816 int32_t outputBufferCnt = DEFAULT_OUT_BUFFER_CNT;
817 format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, inputBufferCnt);
818 format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, outputBufferCnt);
819 inputAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("inputAvailQue", inputBufferCnt);
820 codecAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("codecAvailQue", outputBufferCnt);
821
822 if (AllocateInputBuffer(inputBufferCnt, inputBufferSize_) == AVCS_ERR_NO_MEMORY ||
823 AllocateOutputBuffer(outputBufferCnt, outputBufferSize_) == AVCS_ERR_NO_MEMORY) {
824 return AVCS_ERR_NO_MEMORY;
825 }
826 AVCODEC_LOGI("Allocate buffers successful");
827 return AVCS_ERR_OK;
828 }
829
InitAvcEncoderParams()830 void AvcEncoder::InitAvcEncoderParams()
831 {
832 initParams_.logFxn = nullptr;
833 initParams_.uiChannelID = 0;
834 initParams_.width = 0;
835 initParams_.height = 0;
836 initParams_.frameRate = 0;
837 initParams_.bitrate = 0;
838 initParams_.qp = 0;
839 initParams_.qpMax = 0;
840 initParams_.qpMin = 0;
841 initParams_.iperiod = 0;
842 initParams_.range = 0;
843 initParams_.primaries = 0;
844 initParams_.transfer = 0;
845 initParams_.matrix = 0;
846 initParams_.level = 0;
847 initParams_.encMode = ENC_MODE::MODE_CBR;
848 initParams_.profile = ENC_PROFILE::PROFILE_BASE;
849 initParams_.colorFmt = COLOR_FORMAT::YUV_420SP_VU;
850
851 for (int i = 0; i < IV_MAX_RAW_COMPONENTS; i++) {
852 avcEncInputArgs_.inputBufs[i] = nullptr;
853 avcEncInputArgs_.width[i] = 0;
854 avcEncInputArgs_.height[i] = 0;
855 avcEncInputArgs_.stride[i] = 0;
856 }
857 avcEncInputArgs_.timestamp = 0;
858 avcEncOutputArgs_.streamBuf = nullptr;
859 avcEncOutputArgs_.encodedFrameType = 0;
860 avcEncOutputArgs_.isLast = 0;
861 avcEncOutputArgs_.size = 0;
862 avcEncOutputArgs_.bytes = 0;
863 avcEncOutputArgs_.timestamp = 0;
864 }
865
FillAvcInitParams(AVC_ENC_INIT_PARAM & param)866 void AvcEncoder::FillAvcInitParams(AVC_ENC_INIT_PARAM ¶m)
867 {
868 param.logFxn = AvcEncLog;
869 param.uiChannelID = encInstanceID_;
870 param.width = static_cast<uint32_t>(encWidth_);
871 param.height = static_cast<uint32_t>(encHeight_);
872 param.encMode = TranslateEncMode(bitrateMode_);
873 param.frameRate = static_cast<uint32_t>(encFrameRate_);
874 param.bitrate = static_cast<uint32_t>(encBitrate_);
875 param.qp = static_cast<uint32_t>(encQp_);
876 param.qpMax = static_cast<uint32_t>(encQpMax_);
877 param.qpMin = static_cast<uint32_t>(encQpMin_);
878 param.iperiod = static_cast<uint32_t>(encIperiod_);
879 param.colorFmt = COLOR_FORMAT::YUV_420SP_VU;
880 param.range = srcRange_;
881 param.primaries = static_cast<uint8_t>(srcPrimary_);
882 param.transfer = static_cast<uint8_t>(srcTransfer_);
883 param.matrix = static_cast<uint8_t>(srcMatrix_);
884 param.level = static_cast<uint32_t>(TranslateEncLevel(avcLevel_));
885 param.profile = TranslateEncProfile(avcProfile_);
886 }
887
Start()888 int32_t AvcEncoder::Start()
889 {
890 AVCODEC_SYNC_TRACE;
891 CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Start codec failed: callback is null");
892 CHECK_AND_RETURN_RET_LOG((state_ == State::CONFIGURED || state_ == State::FLUSHED), AVCS_ERR_INVALID_STATE,
893 "Start codec failed: not in Configured or Flushed state");
894
895 if (!isBufferAllocated_) {
896 for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
897 scaleData_[i] = nullptr;
898 scaleLineSize_[i] = 0;
899 }
900 int32_t ret = AllocateBuffers();
901 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Start codec failed: cannot allocate buffers");
902 isBufferAllocated_ = true;
903 }
904
905 uint32_t createRet = 0;
906 FillAvcInitParams(initParams_);
907 std::unique_lock<std::mutex> runLock(encRunMutex_);
908 if (avcEncoder_ == nullptr && avcEncoderCreateFunc_ != nullptr) {
909 createRet = avcEncoderCreateFunc_(&avcEncoder_, &initParams_);
910 }
911 CHECK_AND_RETURN_RET_LOG(createRet == 0 && avcEncoder_ != nullptr, AVCS_ERR_INVALID_OPERATION,
912 "avc encoder create failed");
913 runLock.unlock();
914
915 InitBuffers();
916 isSendEos_ = false;
917 sendTask_->Start();
918 if (inputSurface_ != nullptr) {
919 ClearDirtyList();
920 sptr<IBufferConsumerListener> listener = new EncoderBuffersConsumerListener(this);
921 inputSurface_->RegisterConsumerListener(listener);
922 }
923
924 state_ = State::RUNNING;
925 AVCODEC_LOGI("Start codec successful, state: Running");
926 return AVCS_ERR_OK;
927 }
928
IsActive() const929 bool AvcEncoder::IsActive() const
930 {
931 return state_ == State::RUNNING || state_ == State::FLUSHED || state_ == State::EOS;
932 }
933
ResetData()934 void AvcEncoder::ResetData()
935 {
936 if (scaleData_[0] != nullptr) {
937 av_free(scaleData_[0]);
938 scale_.reset();
939 for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
940 scaleData_[i] = nullptr;
941 scaleLineSize_[i] = 0;
942 }
943 }
944 }
945
ResetBuffers()946 void AvcEncoder::ResetBuffers()
947 {
948 inputAvailQue_->Clear();
949 codecAvailQue_->Clear();
950 freeList_.clear();
951 ResetData();
952 }
953
Stop()954 int32_t AvcEncoder::Stop()
955 {
956 AVCODEC_SYNC_TRACE;
957 CHECK_AND_RETURN_RET_LOG((IsActive()), AVCS_ERR_INVALID_STATE, "Stop codec failed: not in executing state");
958 state_ = State::STOPPING;
959 AVCODEC_LOGI("step into STOPPING status");
960
961 if (inputSurface_ != nullptr) {
962 surfaceRecvCv_.notify_all();
963 ClearDirtyList();
964 inputSurface_->UnregisterConsumerListener();
965 }
966
967 std::unique_lock<std::mutex> sLock(sendMutex_);
968 sendCv_.notify_one();
969 sLock.unlock();
970 inputAvailQue_->SetActive(false, false);
971 codecAvailQue_->SetActive(false, false);
972 sendTask_->Stop();
973 ResetBuffers();
974 std::unique_lock<std::mutex> runLock(encRunMutex_);
975 if (avcEncoder_ != nullptr && avcEncoderDeleteFunc_ != nullptr) {
976 uint32_t ret = avcEncoderDeleteFunc_(avcEncoder_);
977 if (ret != 0) {
978 AVCODEC_LOGE("Error: avc encoder delete error: %{public}d", ret);
979 callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
980 state_ = State::ERROR;
981 }
982 avcEncoder_ = nullptr;
983 }
984 runLock.unlock();
985 state_ = State::CONFIGURED;
986 AVCODEC_LOGI("Stop codec successful, state: Configured");
987 return AVCS_ERR_OK;
988 }
989
Flush()990 int32_t AvcEncoder::Flush()
991 {
992 AVCODEC_SYNC_TRACE;
993 CHECK_AND_RETURN_RET_LOG((state_ == State::RUNNING || state_ == State::EOS), AVCS_ERR_INVALID_STATE,
994 "Flush codec failed: not in running or Eos state");
995 state_ = State::FLUSHING;
996 AVCODEC_LOGI("step into FLUSHING status");
997 std::unique_lock<std::mutex> sLock(sendMutex_);
998 sendCv_.notify_one();
999 sLock.unlock();
1000
1001 inputAvailQue_->SetActive(false, false);
1002 codecAvailQue_->SetActive(false, false);
1003 sendTask_->Pause();
1004
1005 ResetBuffers();
1006 state_ = State::FLUSHED;
1007 AVCODEC_LOGI("Flush codec successful, state: Flushed");
1008 return AVCS_ERR_OK;
1009 }
1010
Reset()1011 int32_t AvcEncoder::Reset()
1012 {
1013 AVCODEC_SYNC_TRACE;
1014 AVCODEC_LOGI("Reset codec called");
1015 int32_t ret = Release();
1016 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot release codec");
1017 ret = Initialize();
1018 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot init codec");
1019 AVCODEC_LOGI("Reset codec successful, state: Initialized");
1020 return AVCS_ERR_OK;
1021 }
1022
StopThread()1023 void AvcEncoder::StopThread()
1024 {
1025 if (sendTask_ != nullptr && inputAvailQue_ != nullptr) {
1026 std::unique_lock<std::mutex> sLock(sendMutex_);
1027 sendCv_.notify_one();
1028 sLock.unlock();
1029 inputAvailQue_->SetActive(false, false);
1030 codecAvailQue_->SetActive(false, false);
1031 sendTask_->Stop();
1032 }
1033 }
1034
ReleaseBuffers()1035 void AvcEncoder::ReleaseBuffers()
1036 {
1037 if (!isBufferAllocated_) {
1038 return;
1039 }
1040
1041 inputAvailQue_->Clear();
1042 std::unique_lock<std::mutex> iLock(inputMutex_);
1043 buffers_[INDEX_INPUT].clear();
1044 iLock.unlock();
1045
1046 std::unique_lock<std::mutex> oLock(outputMutex_);
1047 codecAvailQue_->Clear();
1048 buffers_[INDEX_OUTPUT].clear();
1049 oLock.unlock();
1050
1051 ResetData();
1052 isBufferAllocated_ = false;
1053 }
1054
ReleaseResource()1055 void AvcEncoder::ReleaseResource()
1056 {
1057 StopThread();
1058 ReleaseBuffers();
1059 format_ = Format();
1060
1061 if (inputSurface_ != nullptr) {
1062 surfaceRecvCv_.notify_all();
1063 ClearDirtyList();
1064 inputSurface_->UnregisterConsumerListener();
1065 }
1066
1067 std::unique_lock<std::mutex> runLock(encRunMutex_);
1068 if (avcEncoder_ != nullptr && avcEncoderDeleteFunc_ != nullptr) {
1069 uint32_t ret = avcEncoderDeleteFunc_(avcEncoder_);
1070 if (ret != 0) {
1071 AVCODEC_LOGE("Error: avc encoder delete error: %{public}d", ret);
1072 callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1073 state_ = State::ERROR;
1074 }
1075 avcEncoder_ = nullptr;
1076 }
1077 runLock.unlock();
1078 }
1079
Release()1080 int32_t AvcEncoder::Release()
1081 {
1082 AVCODEC_SYNC_TRACE;
1083 state_ = State::STOPPING;
1084 AVCODEC_LOGI("step into STOPPING status");
1085 ReleaseResource();
1086 state_ = State::UNINITIALIZED;
1087 AVCODEC_LOGI("Release codec successful, state: Uninitialized");
1088 return AVCS_ERR_OK;
1089 }
1090
SetParameter(const Format & format)1091 int32_t AvcEncoder::SetParameter(const Format &format)
1092 {
1093 return ConfigureContext(format);
1094 }
1095
GetInputFormat(Format & format)1096 int32_t AvcEncoder::GetInputFormat(Format &format)
1097 {
1098 format.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, AVCodecCodecName::VIDEO_ENCODER_AVC_NAME);
1099 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, encWidth_);
1100 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, encHeight_);
1101 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE,
1102 static_cast<int>(bitrateMode_));
1103 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT,
1104 static_cast<int32_t>(srcPixelFmt_));
1105 if (srcPixelFmt_ == VideoPixelFormat::RGBA) {
1106 format.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE, encWidth_ * RGBA_COLINC);
1107 } else {
1108 format.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE, encWidth_);
1109 }
1110 AVCODEC_LOGI("GetInputFormat !");
1111 return AVCS_ERR_OK;
1112 }
1113
GetOutputFormat(Format & format)1114 int32_t AvcEncoder::GetOutputFormat(Format &format)
1115 {
1116 format.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, AVCodecCodecName::VIDEO_ENCODER_AVC_NAME);
1117 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, encWidth_);
1118 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, encHeight_);
1119 format.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_WIDTH, encWidth_);
1120 format.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_HEIGHT, encHeight_);
1121 format.PutIntValue(MediaDescriptionKey::MD_KEY_QUALITY, avcQuality_);
1122 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE,
1123 static_cast<int>(bitrateMode_));
1124 AVCODEC_LOGI("GetOutputFormat !");
1125 return AVCS_ERR_OK;
1126 }
1127
GetDiscardFlagFromAVBuffer(const std::shared_ptr<AVBuffer> & buffer)1128 bool AvcEncoder::GetDiscardFlagFromAVBuffer(const std::shared_ptr<AVBuffer> &buffer)
1129 {
1130 bool ret = false;
1131 if (buffer->meta_->GetData(OHOS::Media::Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, ret) && ret) {
1132 AVCODEC_LOGD("discard by user, pts = %{public}" PRId64, buffer->pts_);
1133 return ret;
1134 }
1135 return ret;
1136 }
1137
QueueInputBuffer(uint32_t index)1138 int32_t AvcEncoder::QueueInputBuffer(uint32_t index)
1139 {
1140 AVCODEC_SYNC_TRACE;
1141 if (inputSurface_ != nullptr && !enableSurfaceModeInputCb_) {
1142 return AVCS_ERR_INVALID_STATE;
1143 }
1144
1145 CHECK_AND_RETURN_RET_LOG(state_ == State::RUNNING, AVCS_ERR_INVALID_STATE,
1146 "Queue input buffer failed: not in Running state");
1147 CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_INPUT].size(), AVCS_ERR_INVALID_VAL,
1148 "Queue input buffer failed with bad index, index=%{public}u, buffer_size=%{public}zu",
1149 index, buffers_[INDEX_INPUT].size());
1150 std::shared_ptr<FBuffer> inputBuffer = buffers_[INDEX_INPUT][index];
1151 CHECK_AND_RETURN_RET_LOG(inputBuffer->owner_ == FBuffer::Owner::OWNED_BY_USER, AVCS_ERR_INVALID_OPERATION,
1152 "Queue input buffer failed: buffer with index=%{public}u is not available", index);
1153
1154 if (inputSurface_ != nullptr) {
1155 int64_t pts = inputBuffer->avBuffer_->pts_;
1156 bool discard = GetDiscardFlagFromAVBuffer(inputBuffer->avBuffer_);
1157 inputBuffer->avBuffer_->meta_->Clear();
1158 inputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer(inputBuffer->surfaceBuffer_);
1159 CHECK_AND_RETURN_RET_LOG(inputBuffer->avBuffer_ != nullptr && inputBuffer->avBuffer_->memory_ != nullptr,
1160 AVCS_ERR_INVALID_VAL, "Allocate input buffer failed, index=%{public}u", index);
1161 inputBuffer->avBuffer_->pts_ = pts;
1162 if (discard) {
1163 inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
1164 NotifyUserToFillBuffer(index, inputBuffer->avBuffer_);
1165 return AVCS_ERR_OK;
1166 }
1167 }
1168
1169 inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
1170 inputAvailQue_->Push(index);
1171 return AVCS_ERR_OK;
1172 }
1173
ReleaseOutputBuffer(uint32_t index)1174 int32_t AvcEncoder::ReleaseOutputBuffer(uint32_t index)
1175 {
1176 AVCODEC_SYNC_TRACE;
1177 std::unique_lock<std::mutex> oLock(outputMutex_);
1178 CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_OUTPUT].size(), AVCS_ERR_INVALID_VAL,
1179 "Failed to release output buffer: invalid index");
1180 std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1181 oLock.unlock();
1182 if (frameBuffer->owner_ == FBuffer::Owner::OWNED_BY_USER) {
1183 frameBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
1184 codecAvailQue_->Push(index);
1185 return AVCS_ERR_OK;
1186 } else {
1187 AVCODEC_LOGE("Release output buffer failed: check your index=%{public}u", index);
1188 return AVCS_ERR_INVALID_VAL;
1189 }
1190 }
1191
NotifyEos()1192 int32_t AvcEncoder::NotifyEos()
1193 {
1194 AVCODEC_LOGI(" start ");
1195 WaitForInBuffer();
1196 if (freeList_.empty()) {
1197 AVCODEC_LOGE("no empty buffer");
1198 return AVCS_ERR_OK;
1199 }
1200
1201 std::unique_lock<std::mutex> listLock(freeListMutex_);
1202 uint32_t index = freeList_.front();
1203 freeList_.pop_front();
1204 listLock.unlock();
1205
1206 std::shared_ptr<FBuffer> &inputBuffer = buffers_[INDEX_INPUT][index];
1207 if (inputSurface_ != nullptr) {
1208 inputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer();
1209 CHECK_AND_RETURN_RET_LOG(inputBuffer->avBuffer_ != nullptr, AVCS_ERR_INVALID_VAL,
1210 "Allocate input buffer failed, index=%{public}u", index);
1211 }
1212 inputBuffer->avBuffer_->flag_ = AVCODEC_BUFFER_FLAG_EOS;
1213 inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
1214 inputAvailQue_->Push(index);
1215
1216 AVCODEC_LOGI("push eos buffer %{public}d", index);
1217 return AVCS_ERR_OK;
1218 }
1219
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)1220 int32_t AvcEncoder::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
1221 {
1222 AVCODEC_SYNC_TRACE;
1223 CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Set callback failed: callback is NULL");
1224 callback_ = callback;
1225 return AVCS_ERR_OK;
1226 }
1227
SetOutputSurface(sptr<Surface> surface)1228 int32_t AvcEncoder::SetOutputSurface(sptr<Surface> surface)
1229 {
1230 return AVCS_ERR_OK;
1231 }
1232
RenderOutputBuffer(uint32_t index)1233 int32_t AvcEncoder::RenderOutputBuffer(uint32_t index)
1234 {
1235 return AVCS_ERR_OK;
1236 }
1237
NotifyUserToProcessBuffer(uint32_t index,std::shared_ptr<AVBuffer> & buffer)1238 void AvcEncoder::NotifyUserToProcessBuffer(uint32_t index, std::shared_ptr<AVBuffer> &buffer)
1239 {
1240 callback_->OnOutputBufferAvailable(index, buffer);
1241 }
1242
NotifyUserToFillBuffer(uint32_t index,std::shared_ptr<AVBuffer> & buffer)1243 void AvcEncoder::NotifyUserToFillBuffer(uint32_t index, std::shared_ptr<AVBuffer> &buffer)
1244 {
1245 if (inputSurface_ == nullptr) {
1246 callback_->OnInputBufferAvailable(index, buffer);
1247 } else {
1248 std::unique_lock<std::mutex> listLock(freeListMutex_);
1249 freeList_.emplace_back(index);
1250 listLock.unlock();
1251 surfaceRecvCv_.notify_one();
1252 auto surfaceBuffer = buffer->memory_->GetSurfaceBuffer();
1253 inputSurface_->ReleaseBuffer(surfaceBuffer, -1);
1254 }
1255 }
1256
CheckBufferSize(int32_t bufferSize,int32_t stride,int32_t height,VideoPixelFormat pixelFormat)1257 int32_t AvcEncoder::CheckBufferSize(int32_t bufferSize, int32_t stride, int32_t height, VideoPixelFormat pixelFormat)
1258 {
1259 int32_t expect = 0;
1260 switch (pixelFormat) {
1261 case VideoPixelFormat::RGBA: {
1262 expect = stride * height; // rgba origin stride already * 4
1263 break;
1264 }
1265 case VideoPixelFormat::YUVI420:
1266 case VideoPixelFormat::NV12:
1267 case VideoPixelFormat::NV21: {
1268 expect = stride * height * 3 / 2; // * 3 / 2: yuv size
1269 break;
1270 }
1271 default:
1272 AVCODEC_LOGE("Invalid buffer size %{public}d %{public}dX%{public}d for format:%{public}d",
1273 bufferSize, stride, height, static_cast<int32_t>(pixelFormat));
1274 return AVCS_ERR_UNSUPPORT_SOURCE;
1275 }
1276 if (bufferSize >= expect && expect > 0) {
1277 return AVCS_ERR_OK;
1278 }
1279 return AVCS_ERR_UNSUPPORT_SOURCE;
1280 }
1281
FillNV21ToAvcEncInArgs(AVC_ENC_INARGS & inArgs,NVFrame & nvFrame,int64_t pts)1282 void AvcEncoder::FillNV21ToAvcEncInArgs(AVC_ENC_INARGS &inArgs, NVFrame &nvFrame, int64_t pts)
1283 {
1284 inArgs.inputBufs[0] = nvFrame.srcY;
1285 inArgs.inputBufs[1] = nvFrame.srcUV;
1286 inArgs.width[0] = static_cast<uint32_t>(nvFrame.width);
1287 inArgs.width[1] = static_cast<uint32_t>(nvFrame.width);
1288 inArgs.height[0] = static_cast<uint32_t>(nvFrame.height);
1289 inArgs.height[1] = static_cast<uint32_t>(nvFrame.height) >> 1;
1290 inArgs.stride[0] = static_cast<uint32_t>(nvFrame.yStride);
1291 inArgs.stride[1] = static_cast<uint32_t>(nvFrame.uvStide);
1292
1293 inArgs.colorFmt = COLOR_FORMAT::YUV_420SP_VU;
1294 inArgs.timestamp = static_cast<uint64_t>(pts);
1295 inArgs.configArgs.bitrate = static_cast<uint32_t>(encBitrate_);
1296 inArgs.configArgs.idrRequest = encIdrRequest_ ? 1 : 0;
1297 encIdrRequest_ = false;
1298 }
1299
FillAvcEncoderInDefaultArgs(AVC_ENC_INARGS & inArgs)1300 int32_t AvcEncoder::FillAvcEncoderInDefaultArgs(AVC_ENC_INARGS &inArgs)
1301 {
1302 inArgs.colorFmt = COLOR_FORMAT::YUV_420SP_VU;
1303 for (int i = 0; i < IV_MAX_RAW_COMPONENTS; i++) {
1304 inArgs.inputBufs[i] = nullptr;
1305 inArgs.width[i] = 0;
1306 inArgs.height[i] = 0;
1307 inArgs.stride[i] = 0;
1308 }
1309 return AVCS_ERR_OK;
1310 }
1311
Nv21ToAvcEncoderInArgs(InputFrame & inFrame,AVC_ENC_INARGS & inArgs)1312 int32_t AvcEncoder::Nv21ToAvcEncoderInArgs(InputFrame &inFrame, AVC_ENC_INARGS &inArgs)
1313 {
1314 NVFrame nvFrame = {
1315 .srcY = inFrame.buffer,
1316 .srcUV = inFrame.buffer + inFrame.uvOffset,
1317 .yStride = inFrame.stride,
1318 .uvStide = inFrame.stride,
1319 .width = inFrame.width,
1320 .height = inFrame.height,
1321 };
1322
1323 FillNV21ToAvcEncInArgs(inArgs, nvFrame, inFrame.pts);
1324 return AVCS_ERR_OK;
1325 }
1326
Nv12ToAvcEncoderInArgs(InputFrame & inFrame,AVC_ENC_INARGS & inArgs)1327 int32_t AvcEncoder::Nv12ToAvcEncoderInArgs(InputFrame &inFrame, AVC_ENC_INARGS &inArgs)
1328 {
1329 int32_t width = inFrame.width;
1330 int32_t height = inFrame.height;
1331 uint8_t *dstData = convertBuffer_->memory_->GetAddr();
1332 int32_t dstSize = convertBuffer_->memory_->GetCapacity();
1333
1334 YuvImageData yuvData = {
1335 .data = inFrame.buffer,
1336 .stride = inFrame.stride,
1337 .uvOffset = inFrame.uvOffset,
1338 };
1339
1340 int32_t ret = ConvertNv12ToNv21(dstData, width, height, dstSize, yuvData);
1341 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Scale video frame failed: %{public}d", ret);
1342
1343 NVFrame nvFrame = {
1344 .srcY = dstData,
1345 .srcUV = dstData + width * height,
1346 .yStride = width,
1347 .uvStide = width,
1348 .width = width,
1349 .height = height,
1350 };
1351
1352 FillNV21ToAvcEncInArgs(inArgs, nvFrame, inFrame.pts);
1353 return AVCS_ERR_OK;
1354 }
1355
Yuv420ToAvcEncoderInArgs(InputFrame & inFrame,AVC_ENC_INARGS & inArgs)1356 int32_t AvcEncoder::Yuv420ToAvcEncoderInArgs(InputFrame &inFrame, AVC_ENC_INARGS &inArgs)
1357 {
1358 uint8_t* srcData[AV_NUM_DATA_POINTERS] = {
1359 inFrame.buffer,
1360 inFrame.buffer + inFrame.uvOffset,
1361 inFrame.buffer + inFrame.uvOffset + (inFrame.stride / 2) * (inFrame.height / 2), // v: 1/2 width, 1/2 height
1362 };
1363 int32_t srcLineSize[AV_NUM_DATA_POINTERS] = {
1364 inFrame.stride,
1365 inFrame.stride / 2, // 2: u stride
1366 inFrame.stride / 2 // 2: v stride
1367 };
1368
1369 int32_t ret = ConvertVideoFrame(&scale_,
1370 srcData, srcLineSize, ConvertPixelFormatToFFmpeg(VideoPixelFormat::YUVI420),
1371 inFrame.width, inFrame.height,
1372 scaleData_, scaleLineSize_, ConvertPixelFormatToFFmpeg(VideoPixelFormat::NV21));
1373 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Scale video frame failed: %{public}d", ret);
1374
1375 NVFrame nvFrame = {
1376 .srcY = scaleData_[0],
1377 .srcUV = scaleData_[1],
1378 .yStride = scaleLineSize_[0],
1379 .uvStide = scaleLineSize_[1],
1380 .width = inFrame.width,
1381 .height = inFrame.height,
1382 };
1383
1384 FillNV21ToAvcEncInArgs(inArgs, nvFrame, inFrame.pts);
1385 return AVCS_ERR_OK;
1386 }
1387
RgbaToAvcEncoderInArgs(InputFrame & inFrame,AVC_ENC_INARGS & inArgs)1388 int32_t AvcEncoder::RgbaToAvcEncoderInArgs(InputFrame &inFrame, AVC_ENC_INARGS &inArgs)
1389 {
1390 int32_t width = inFrame.width;
1391 int32_t height = inFrame.height;
1392 int32_t stride = inFrame.stride;
1393
1394 if (inputSurface_ != nullptr) {
1395 stride = inFrame.stride / RGBA_COLINC; // surface buffer rgba stride has * 4
1396 }
1397
1398 uint8_t *dstData = convertBuffer_->memory_->GetAddr();
1399 int32_t dstSize = convertBuffer_->memory_->GetCapacity();
1400
1401 RgbImageData rgbData = {
1402 .data = inFrame.buffer,
1403 .stride = stride,
1404 .matrix = TranslateMatrix(srcMatrix_),
1405 .range = TranslateRange(srcRange_),
1406 .bytesPerPixel = RGBA_COLINC,
1407 };
1408
1409 int32_t ret = AVCS_ERR_OK;
1410 #if defined(ARMV8)
1411 ret = ConvertRgbToNv21Neon(dstData, width, height, dstSize, rgbData);
1412 #else
1413 ret = ConvertRgbToNv21(dstData, width, height, dstSize, rgbData);
1414 #endif
1415 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Scale video frame failed: %{public}d", ret);
1416
1417 NVFrame nvFrame = {
1418 .srcY = dstData,
1419 .srcUV = dstData + width * height,
1420 .yStride = width,
1421 .uvStide = width,
1422 .width = width,
1423 .height = height,
1424 };
1425 FillNV21ToAvcEncInArgs(inArgs, nvFrame, inFrame.pts);
1426 return AVCS_ERR_OK;
1427 }
1428
GetSurfaceBufferUvOffset(sptr<SurfaceBuffer> & surfaceBuffer,VideoPixelFormat format)1429 int32_t AvcEncoder::GetSurfaceBufferUvOffset(sptr<SurfaceBuffer> &surfaceBuffer, VideoPixelFormat format)
1430 {
1431 int32_t uvOffset = 0;
1432 if (!((format == VideoPixelFormat::YUVI420) ||
1433 (format == VideoPixelFormat::NV12) ||
1434 (format == VideoPixelFormat::NV21))) {
1435 return uvOffset;
1436 }
1437
1438 OH_NativeBuffer_Planes *planes = nullptr;
1439 GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
1440 if (retVal != GSERROR_OK || planes == nullptr) {
1441 AVCODEC_LOGE(" GetPlanesInfo failed, retVal:%{public}d", retVal);
1442 return uvOffset;
1443 }
1444 CHECK_AND_RETURN_RET_LOG(planes->planeCount > 1, uvOffset, "Get surface uvinfo failed");
1445 if (format == VideoPixelFormat::NV21) {
1446 uvOffset = static_cast<int32_t>(planes->planes[2].offset); // 2: nv21 v offset
1447 } else {
1448 uvOffset = static_cast<int32_t>(planes->planes[1].offset); // 1: nv21 yuv420 u offset
1449 }
1450 return uvOffset;
1451 }
1452
GetInputFrameFromAVBuffer(std::shared_ptr<AVBuffer> & buffer,InputFrame & inFrame)1453 int32_t AvcEncoder::GetInputFrameFromAVBuffer(std::shared_ptr<AVBuffer> &buffer, InputFrame &inFrame)
1454 {
1455 inFrame.format = srcPixelFmt_;
1456 inFrame.width = encWidth_;
1457 inFrame.height = encHeight_;
1458 inFrame.stride = encWidth_;
1459 inFrame.size = buffer->memory_->GetSize();
1460 inFrame.buffer = buffer->memory_->GetAddr();
1461 if (inputSurface_ != nullptr) {
1462 auto surfaceBuffer = buffer->memory_->GetSurfaceBuffer();
1463 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, AVCS_ERR_INVALID_DATA, "Get surface data failed!");
1464 inFrame.format =
1465 TranslateVideoPixelFormat(static_cast<GraphicPixelFormat>(surfaceBuffer->GetFormat()));
1466 inFrame.width = surfaceBuffer->GetWidth();
1467 CHECK_AND_RETURN_RET_LOG((inFrame.width >= VIDEO_MIN_SIZE) && (inFrame.width <= VIDEO_MAX_WIDTH_SIZE),
1468 AVCS_ERR_INVALID_DATA, "Get surface width failed!");
1469 inFrame.height = surfaceBuffer->GetHeight();
1470 CHECK_AND_RETURN_RET_LOG((inFrame.height >= VIDEO_MIN_SIZE) && (inFrame.height <= VIDEO_MAX_HEIGHT_SIZE),
1471 AVCS_ERR_INVALID_DATA, "Get surface height failed!");
1472 inFrame.stride = surfaceBuffer->GetStride();
1473 CHECK_AND_RETURN_RET_LOG(inFrame.stride >= inFrame.width, AVCS_ERR_INVALID_DATA,
1474 "Get surface stride failed!");
1475 inFrame.size = static_cast<int32_t>(surfaceBuffer->GetSize());
1476 inFrame.buffer = reinterpret_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
1477 CHECK_AND_RETURN_RET_LOG(inFrame.buffer != nullptr, AVCS_ERR_INVALID_DATA,
1478 "Get surface buffer failed!");
1479 inFrame.uvOffset = GetSurfaceBufferUvOffset(surfaceBuffer, inFrame.format);
1480 }
1481 if (inFrame.uvOffset == 0) {
1482 inFrame.uvOffset = inFrame.stride * inFrame.height;
1483 }
1484 inFrame.pts = buffer->pts_;
1485 return AVCS_ERR_OK;
1486 }
1487
FillAvcEncoderInArgs(std::shared_ptr<AVBuffer> & buffer,AVC_ENC_INARGS & inArgs)1488 int32_t AvcEncoder::FillAvcEncoderInArgs(std::shared_ptr<AVBuffer> &buffer, AVC_ENC_INARGS &inArgs)
1489 {
1490 InputFrame inFrame;
1491 int32_t ret = GetInputFrameFromAVBuffer(buffer, inFrame);
1492 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_DATA, "Get input frame failed!");
1493
1494 ret = CheckBufferSize(inFrame.size, inFrame.stride, inFrame.height, inFrame.format);
1495 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Check buffer size failed!");
1496
1497 switch (inFrame.format) {
1498 case VideoPixelFormat::YUVI420: {
1499 return Yuv420ToAvcEncoderInArgs(inFrame, inArgs);
1500 }
1501 case VideoPixelFormat::RGBA: {
1502 return RgbaToAvcEncoderInArgs(inFrame, inArgs);
1503 }
1504 case VideoPixelFormat::NV12: {
1505 return Nv12ToAvcEncoderInArgs(inFrame, inArgs);
1506 }
1507 case VideoPixelFormat::NV21: {
1508 return Nv21ToAvcEncoderInArgs(inFrame, inArgs);
1509 }
1510 default:
1511 AVCODEC_LOGE("Invalid video pixel format:%{public}d",
1512 static_cast<int32_t>(inFrame.format));
1513 }
1514 return AVCS_ERR_UNSUPPORT;
1515 }
1516
EncoderAvcFrame(AVC_ENC_INARGS & inArgs,AVC_ENC_OUTARGS & outArgs)1517 int32_t AvcEncoder::EncoderAvcFrame(AVC_ENC_INARGS &inArgs, AVC_ENC_OUTARGS &outArgs)
1518 {
1519 uint32_t ret = 0;
1520 std::unique_lock<std::mutex> sLock(encRunMutex_);
1521 if (avcEncoder_ == nullptr || avcEncoderFrameFunc_ == nullptr) {
1522 AVCODEC_LOGE("Avc encoder load error !");
1523 return AVCS_ERR_VID_ENC_FAILED;
1524 }
1525
1526 uint32_t codecIndex = codecAvailQue_->Front();
1527 std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][codecIndex];
1528 std::shared_ptr<AVBuffer> &outputAVBuffer = outputBuffer->avBuffer_;
1529
1530 outArgs.streamBuf = outputAVBuffer->memory_->GetAddr();
1531 outArgs.size = static_cast<uint32_t>(outputAVBuffer->memory_->GetCapacity());
1532
1533 ret = avcEncoderFrameFunc_(avcEncoder_, &inArgs, &outArgs);
1534 sLock.unlock();
1535 if (ret == 0) {
1536 outputAVBuffer->memory_->SetSize(outArgs.bytes);
1537 outputAVBuffer->pts_ = static_cast<int64_t>(outArgs.timestamp);
1538 outputAVBuffer->flag_ = AvcFrameTypeToBufferFlag(outArgs.encodedFrameType);
1539 } else {
1540 outputAVBuffer->flag_ = AVCODEC_BUFFER_FLAG_NONE;
1541 AVCODEC_LOGE("Cannot send frame to encodec: %{public}d", ret);
1542 }
1543
1544 if (isSendEos_) {
1545 outputAVBuffer->flag_ = AVCODEC_BUFFER_FLAG_EOS;
1546 }
1547
1548 outputBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
1549 codecAvailQue_->Pop();
1550 NotifyUserToProcessBuffer(codecIndex, outputAVBuffer);
1551 return AVCS_ERR_OK;
1552 }
1553
EncoderAvcHeader()1554 void AvcEncoder::EncoderAvcHeader()
1555 {
1556 AVC_ENC_INARGS headerInArgs;
1557 FillAvcEncoderInDefaultArgs(headerInArgs);
1558 int32_t ret = EncoderAvcFrame(headerInArgs, avcEncOutputArgs_);
1559 CHECK_AND_RETURN_LOG(ret == AVCS_ERR_OK, "Avc Encoder header error: %{public}d", ret);
1560 }
1561
EncoderAvcTailer()1562 void AvcEncoder::EncoderAvcTailer()
1563 {
1564 AVC_ENC_INARGS eosInArgs;
1565 FillAvcEncoderInDefaultArgs(eosInArgs);
1566 int32_t ret = EncoderAvcFrame(eosInArgs, avcEncOutputArgs_);
1567 CHECK_AND_RETURN_LOG(ret == AVCS_ERR_OK, "Avc Encoder tailer error: %{public}d", ret);
1568 }
1569
SendFrame()1570 void AvcEncoder::SendFrame()
1571 {
1572 CHECK_AND_RETURN_LOG(state_ != State::STOPPING && state_ != State::FLUSHING, "Invalid state");
1573
1574 if (state_ != State::RUNNING || isSendEos_) {
1575 std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_ENCODE_TIME));
1576 return;
1577 }
1578
1579 int32_t ret = AVCS_ERR_OK;
1580 uint32_t index = inputAvailQue_->Front();
1581 CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1582 std::shared_ptr<FBuffer> &inputBuffer = buffers_[INDEX_INPUT][index];
1583 std::shared_ptr<AVBuffer> &inputAVBuffer = inputBuffer->avBuffer_;
1584 if (inputAVBuffer->flag_ & AVCODEC_BUFFER_FLAG_EOS) {
1585 std::unique_lock<std::mutex> sendLock(sendMutex_);
1586 isSendEos_ = true;
1587 EncoderAvcTailer();
1588 state_ = State::EOS;
1589 sendCv_.wait_for(sendLock, std::chrono::milliseconds(DEFAULT_ENCODE_WAIT_TIME));
1590 AVCODEC_LOGI("Send eos end");
1591 return;
1592 }
1593
1594 ret = FillAvcEncoderInArgs(inputAVBuffer, avcEncInputArgs_);
1595 if (ret != AVCS_ERR_OK) {
1596 AVCODEC_LOGE("convert buffer to encodec error: %{public}d", ret);
1597 callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1598 state_ = State::ERROR;
1599 return;
1600 }
1601
1602 if (isFirstFrame_) {
1603 EncoderAvcHeader();
1604 isFirstFrame_ = false;
1605 }
1606
1607 ret = EncoderAvcFrame(avcEncInputArgs_, avcEncOutputArgs_);
1608 if (ret == AVCS_ERR_OK) {
1609 inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
1610 inputAvailQue_->Pop();
1611 NotifyUserToFillBuffer(index, inputAVBuffer);
1612 } else {
1613 AVCODEC_LOGE("Cannot send frame to encodec: %{public}d", ret);
1614 callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1615 state_ = State::ERROR;
1616 }
1617 }
1618
CheckAvcEncLibStatus()1619 int32_t AvcEncoder::CheckAvcEncLibStatus()
1620 {
1621 void* handle = dlopen(AVC_ENC_LIB_PATH, RTLD_LAZY);
1622 if (handle != nullptr) {
1623 auto avcEncoderCreateFunc = reinterpret_cast<CreateAvcEncoderFuncType>(
1624 dlsym(handle, AVC_ENC_CREATE_FUNC_NAME));
1625 auto avcEncoderFrameFunc = reinterpret_cast<EncodeFuncType>(
1626 dlsym(handle, AVC_ENC_ENCODE_FRAME_FUNC_NAME));
1627 auto avcEncoderDeleteFunc = reinterpret_cast<DeleteFuncType>(
1628 dlsym(handle, AVC_ENC_DELETE_FUNC_NAME));
1629 if (avcEncoderCreateFunc == nullptr || avcEncoderFrameFunc == nullptr ||
1630 avcEncoderDeleteFunc == nullptr) {
1631 AVCODEC_LOGE("AvcEncoder avcFuncMatch_ failed!");
1632 avcEncoderCreateFunc = nullptr;
1633 avcEncoderFrameFunc = nullptr;
1634 avcEncoderDeleteFunc = nullptr;
1635 dlclose(handle);
1636 handle = nullptr;
1637 }
1638 }
1639
1640 if (handle == nullptr) {
1641 return AVCS_ERR_UNSUPPORT;
1642 }
1643 dlclose(handle);
1644 handle = nullptr;
1645
1646 return AVCS_ERR_OK;
1647 }
1648
GetCapabilityData(CapabilityData & capsData,uint32_t index)1649 void AvcEncoder::GetCapabilityData(CapabilityData &capsData, uint32_t index)
1650 {
1651 capsData.codecName = static_cast<std::string>(SUPPORT_VCODEC[index].codecName);
1652 capsData.mimeType = static_cast<std::string>(SUPPORT_VCODEC[index].mimeType);
1653 capsData.codecType = SUPPORT_VCODEC[index].isEncoder ? AVCODEC_TYPE_VIDEO_ENCODER : AVCODEC_TYPE_VIDEO_DECODER;
1654 capsData.isVendor = false;
1655 capsData.maxInstance = VIDEO_INSTANCE_SIZE;
1656 capsData.alignment.width = VIDEO_ALIGNMENT_SIZE;
1657 capsData.alignment.height = VIDEO_ALIGNMENT_SIZE;
1658 capsData.width.minVal = VIDEO_MIN_SIZE;
1659 capsData.width.maxVal = VIDEO_MAX_WIDTH_SIZE;
1660 capsData.height.minVal = VIDEO_MIN_SIZE;
1661 capsData.height.maxVal = VIDEO_MAX_HEIGHT_SIZE;
1662 capsData.frameRate.minVal = VIDEO_FRAMERATE_MIN_SIZE;
1663 capsData.frameRate.maxVal = VIDEO_FRAMERATE_MAX_SIZE;
1664 capsData.bitrate.minVal = VIDEO_BITRATE_MIN_SIZE;
1665 capsData.bitrate.maxVal = VIDEO_BITRATE_MAX_SIZE;
1666 capsData.blockPerFrame.minVal = 1;
1667 capsData.blockPerFrame.maxVal = VIDEO_BLOCKPERFRAME_SIZE;
1668 capsData.blockPerSecond.minVal = 1;
1669 capsData.blockPerSecond.maxVal = VIDEO_BLOCKPERSEC_SIZE;
1670 capsData.blockSize.width = VIDEO_ALIGN_SIZE;
1671 capsData.blockSize.height = VIDEO_ALIGN_SIZE;
1672 if (SUPPORT_VCODEC[index].isEncoder) {
1673 capsData.complexity.minVal = 1;
1674 capsData.complexity.maxVal = 1;
1675 capsData.encodeQuality.minVal = VIDEO_QUALITY_MIN;
1676 capsData.encodeQuality.maxVal = VIDEO_QUALITY_MAX;
1677 }
1678 capsData.pixFormat = {
1679 static_cast<int32_t>(VideoPixelFormat::YUVI420), static_cast<int32_t>(VideoPixelFormat::NV12),
1680 static_cast<int32_t>(VideoPixelFormat::NV21), static_cast<int32_t>(VideoPixelFormat::RGBA)
1681 };
1682 capsData.bitrateMode = {
1683 static_cast<int32_t>(VideoEncodeBitrateMode::CBR), static_cast<int32_t>(VideoEncodeBitrateMode::VBR),
1684 static_cast<int32_t>(VideoEncodeBitrateMode::CQ)
1685 };
1686 capsData.profiles = {static_cast<int32_t>(AVC_PROFILE_BASELINE), static_cast<int32_t>(AVC_PROFILE_MAIN)};
1687 std::vector<int32_t> levels;
1688 for (int32_t j = 0; j <= static_cast<int32_t>(AVCLevel::AVC_LEVEL_51); ++j) {
1689 levels.emplace_back(j);
1690 }
1691 capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_MAIN), levels));
1692 capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_BASELINE), levels));
1693 return;
1694 }
1695
GetCodecCapability(std::vector<CapabilityData> & capaArray)1696 int32_t AvcEncoder::GetCodecCapability(std::vector<CapabilityData> &capaArray)
1697 {
1698 CHECK_AND_RETURN_RET_LOG(CheckAvcEncLibStatus() == AVCS_ERR_OK,
1699 AVCS_ERR_UNSUPPORT, "avc encoder libs not available");
1700
1701 for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
1702 CapabilityData capsData;
1703 GetCapabilityData(capsData, i);
1704 capaArray.emplace_back(capsData);
1705 }
1706 return AVCS_ERR_OK;
1707 }
1708
1709 std::mutex AvcEncoder::encoderCountMutex_;
1710 std::vector<uint32_t> AvcEncoder::encInstanceIDSet_;
1711 std::vector<uint32_t> AvcEncoder::freeIDSet_;
1712
1713 } // namespace Codec
1714 } // namespace MediaAVCodec
1715 } // namespace OHOS