• 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 = 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 &param)
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