• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param)
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