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