• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "fcodec.h"
17 #include <iostream>
18 #include <set>
19 #include <thread>
20 #include <malloc.h>
21 #include "syspara/parameters.h"
22 #include "securec.h"
23 #include "avcodec_trace.h"
24 #include "avcodec_log.h"
25 #include "utils.h"
26 #include "avcodec_codec_name.h"
27 
28 namespace OHOS {
29 namespace MediaAVCodec {
30 namespace Codec {
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "FCodec"};
33 constexpr uint32_t INDEX_INPUT = 0;
34 constexpr uint32_t INDEX_OUTPUT = 1;
35 constexpr int32_t DEFAULT_IN_BUFFER_CNT = 4;
36 constexpr int32_t DEFAULT_OUT_SURFACE_CNT = 4;
37 constexpr int32_t DEFAULT_OUT_BUFFER_CNT = 3;
38 constexpr int32_t DEFAULT_MIN_BUFFER_CNT = 2;
39 constexpr uint32_t VIDEO_PIX_DEPTH_YUV = 3;
40 constexpr int32_t VIDEO_MIN_BUFFER_SIZE = 1474560;
41 constexpr int32_t VIDEO_MIN_SIZE = 2;
42 constexpr int32_t VIDEO_ALIGNMENT_SIZE = 2;
43 constexpr int32_t VIDEO_MAX_WIDTH_SIZE = 4096;
44 constexpr int32_t VIDEO_MAX_HEIGHT_SIZE = 4096;
45 constexpr int32_t VIDEO_MAX_WIDTH_H263_SIZE = 2048;
46 constexpr int32_t VIDEO_MAX_HEIGHT_H263_SIZE = 1152;
47 constexpr int32_t VIDEO_MIN_WIDTH_H263_SIZE = 20;
48 constexpr int32_t VIDEO_MIN_HEIGHT_H263_SIZE = 20;
49 constexpr int32_t DEFAULT_VIDEO_WIDTH = 1920;
50 constexpr int32_t DEFAULT_VIDEO_HEIGHT = 1080;
51 constexpr uint32_t DEFAULT_TRY_DECODE_TIME = 1;
52 constexpr uint32_t DEFAULT_DECODE_WAIT_TIME = 200;
53 constexpr int32_t VIDEO_INSTANCE_SIZE = 64;
54 constexpr int32_t VIDEO_BITRATE_MAX_SIZE = 300000000;
55 constexpr int32_t VIDEO_FRAMERATE_MAX_SIZE = 120;
56 constexpr int32_t VIDEO_FRAMERATE_DEFAULT_SIZE = 60;
57 constexpr int32_t VIDEO_BLOCKPERFRAME_SIZE = 36864;
58 constexpr int32_t VIDEO_BLOCKPERSEC_SIZE = 983040;
59 constexpr int32_t DEFAULT_THREAD_COUNT = 2;
60 #ifdef BUILD_ENG_VERSION
61 constexpr uint32_t PATH_MAX_LEN = 128;
62 constexpr char DUMP_PATH[] = "/data/misc/fcodecdump";
63 #endif // BUILD_ENG_VERSION
64 constexpr struct {
65     const std::string_view codecName;
66     const std::string_view mimeType;
67     const char *ffmpegCodec;
68     const bool isEncoder;
69 } SUPPORT_VCODEC[] = {
70     {AVCodecCodecName::VIDEO_DECODER_AVC_NAME, CodecMimeType::VIDEO_AVC, "h264", false},
71     {AVCodecCodecName::VIDEO_DECODER_H263_NAME, CodecMimeType::VIDEO_H263, "h263", false},
72     {AVCodecCodecName::VIDEO_DECODER_MPEG2_NAME, CodecMimeType::VIDEO_MPEG2, "mpeg2video", false},
73     {AVCodecCodecName::VIDEO_DECODER_MPEG4_NAME, CodecMimeType::VIDEO_MPEG4, "mpeg4", false},
74 #ifdef SUPPORT_CODEC_RV
75     {AVCodecCodecName::VIDEO_DECODER_RV30_NAME, CodecMimeType::VIDEO_RV30, "rv30", false},
76     {AVCodecCodecName::VIDEO_DECODER_RV40_NAME, CodecMimeType::VIDEO_RV40, "rv40", false},
77 #endif
78 };
79 constexpr uint32_t SUPPORT_VCODEC_NUM = sizeof(SUPPORT_VCODEC) / sizeof(SUPPORT_VCODEC[0]);
80 static std::map<uint64_t, int32_t> g_surfaceCntMap;
81 static std::mutex g_surfaceMapMutex;
82 } // namespace
83 using namespace OHOS::Media;
84 
FCodec(const std::string & name)85 FCodec::FCodec(const std::string &name) : codecName_(name), state_(State::UNINITIALIZED) {}
86 
~FCodec()87 FCodec::~FCodec()
88 {
89     ReleaseResource();
90     callback_ = nullptr;
91 #ifdef BUILD_ENG_VERSION
92     if (dumpInFile_ != nullptr) {
93         dumpInFile_->close();
94     }
95     if (dumpOutFile_ != nullptr) {
96         dumpOutFile_->close();
97     }
98 #endif // BUILD_ENG_VERSION
99     mallopt(M_FLUSH_THREAD_CACHE, 0);
100 }
101 
102 #ifdef BUILD_ENG_VERSION
OpenDumpFile()103 void FCodec::OpenDumpFile()
104 {
105     std::string dumpModeStr = OHOS::system::GetParameter("fcodec.dump", "0");
106     AVCODEC_LOGI("dumpModeStr %{public}s", dumpModeStr.c_str());
107     CHECK_AND_RETURN_LOG(dumpModeStr.length() == 2, "dumpModeStr length should equal 2"); // 2
108     char fileName[PATH_MAX_LEN] = {0};
109     int ret;
110     if (dumpModeStr[0] == '1') {
111         ret = sprintf_s(fileName, sizeof(fileName), "%s/input_%p.h264", DUMP_PATH, this);
112         CHECK_AND_RETURN_LOG(ret > 0, "Fail to sprintf input fileName");
113         dumpInFile_ = std::make_shared<std::ofstream>();
114         dumpInFile_->open(fileName, std::ios::out | std::ios::binary);
115         if (!dumpInFile_->is_open()) {
116             AVCODEC_LOGW("fail open file %{public}s", fileName);
117             dumpInFile_ = nullptr;
118         }
119     }
120 
121     if (dumpModeStr[1] == '1') {
122         ret = sprintf_s(fileName, sizeof(fileName), "%s/output_%p.yuv", DUMP_PATH, this);
123         CHECK_AND_RETURN_LOG(ret > 0, "Fail to sprintf output fileName");
124         dumpOutFile_ = std::make_shared<std::ofstream>();
125         dumpOutFile_->open(fileName, std::ios::out | std::ios::binary);
126         if (!dumpOutFile_->is_open()) {
127             AVCODEC_LOGW("fail open file %{public}s", fileName);
128             dumpOutFile_ = nullptr;
129         }
130     }
131 }
132 #endif // BUILD_ENG_VERSION
133 
Initialize()134 int32_t FCodec::Initialize()
135 {
136     AVCODEC_SYNC_TRACE;
137     CHECK_AND_RETURN_RET_LOG(!codecName_.empty(), AVCS_ERR_INVALID_VAL, "Init codec failed:  empty name");
138     std::string fcodecName;
139     std::string_view mime;
140     for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
141         if (SUPPORT_VCODEC[i].codecName == codecName_) {
142             fcodecName = SUPPORT_VCODEC[i].ffmpegCodec;
143             mime = SUPPORT_VCODEC[i].mimeType;
144             break;
145         }
146     }
147     CHECK_AND_RETURN_RET_LOG(!fcodecName.empty(), AVCS_ERR_INVALID_VAL,
148                              "Init codec failed: not support name: %{public}s", codecName_.c_str());
149     format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, mime);
150     format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, codecName_);
151     avCodec_ = std::shared_ptr<AVCodec>(const_cast<AVCodec *>(avcodec_find_decoder_by_name(fcodecName.c_str())),
152                                         [](void *ptr) {});
153     CHECK_AND_RETURN_RET_LOG(avCodec_ != nullptr, AVCS_ERR_INVALID_VAL,
154                              "Init codec failed:  cannot find codec with name %{public}s", codecName_.c_str());
155     sendTask_ = std::make_shared<TaskThread>("SendFrame");
156     sendTask_->RegisterHandler([this] { SendFrame(); });
157     receiveTask_ = std::make_shared<TaskThread>("ReceiveFrame");
158     receiveTask_->RegisterHandler([this] { ReceiveFrame(); });
159 #ifdef BUILD_ENG_VERSION
160     OpenDumpFile();
161 #endif // BUILD_ENG_VERSION
162     state_ = State::INITIALIZED;
163     AVCODEC_LOGI("Init codec successful,  state: Uninitialized -> Initialized");
164     return AVCS_ERR_OK;
165 }
166 
ConfigureDefaultVal(const Format & format,const std::string_view & formatKey,int32_t minVal,int32_t maxVal)167 void FCodec::ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal,
168                                  int32_t maxVal)
169 {
170     int32_t val32 = 0;
171     if (format.GetIntValue(formatKey, val32) && val32 >= minVal && val32 <= maxVal) {
172         format_.PutIntValue(formatKey, val32);
173     } else {
174         AVCODEC_LOGW("Set parameter failed: %{public}s, which minimum threshold=%{public}d, "
175                      "maximum threshold=%{public}d",
176                      std::string(formatKey).c_str(), minVal, maxVal);
177     }
178 }
179 
ConfigureSurface(const Format & format,const std::string_view & formatKey,FormatDataType formatType)180 void FCodec::ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType)
181 {
182     CHECK_AND_RETURN_LOG(formatType == FORMAT_TYPE_INT32, "Set parameter failed: type should be int32");
183 
184     int32_t val = 0;
185     CHECK_AND_RETURN_LOG(format.GetIntValue(formatKey, val), "Set parameter failed: get value fail");
186 
187     if (formatKey == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
188         VideoPixelFormat vpf = static_cast<VideoPixelFormat>(val);
189         CHECK_AND_RETURN_LOG(vpf == VideoPixelFormat::RGBA || vpf == VideoPixelFormat::YUVI420 ||
190                              vpf == VideoPixelFormat::NV12 || vpf == VideoPixelFormat::NV21,
191                              "Set parameter failed: pixel format value %{public}d invalid", val);
192         outputPixelFmt_ = vpf;
193         format_.PutIntValue(formatKey, val);
194     } else if (formatKey == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE) {
195         VideoRotation sr = static_cast<VideoRotation>(val);
196         CHECK_AND_RETURN_LOG(sr == VideoRotation::VIDEO_ROTATION_0 || sr == VideoRotation::VIDEO_ROTATION_90 ||
197                              sr == VideoRotation::VIDEO_ROTATION_180 || sr == VideoRotation::VIDEO_ROTATION_270,
198                              "Set parameter failed: rotation angle value %{public}d invalid", val);
199         format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val);
200     } else {
201         ScalingMode scaleMode = static_cast<ScalingMode>(val);
202         CHECK_AND_RETURN_LOG(scaleMode == ScalingMode::SCALING_MODE_SCALE_TO_WINDOW ||
203                              scaleMode == ScalingMode::SCALING_MODE_SCALE_CROP,
204                              "Set parameter failed: scale type value %{public}d invalid", val);
205         format_.PutIntValue(formatKey, val);
206     }
207     AVCODEC_LOGI("Set parameter %{public}s success, val %{public}d", std::string(formatKey).c_str(), val);
208 }
209 
ConfigureContext(const Format & format)210 int32_t FCodec::ConfigureContext(const Format &format)
211 {
212     avCodecContext_ = std::shared_ptr<AVCodecContext>(avcodec_alloc_context3(avCodec_.get()), [](AVCodecContext *p) {
213         if (p != nullptr) {
214             if (p->extradata) {
215                 av_free(p->extradata);
216                 p->extradata = nullptr;
217             }
218             avcodec_free_context(&p);
219         }
220     });
221     CHECK_AND_RETURN_RET_LOG(avCodecContext_ != nullptr, AVCS_ERR_INVALID_OPERATION,
222                              "Configure codec failed: Allocate context error");
223     avCodecContext_->codec_type = AVMEDIA_TYPE_VIDEO;
224     CHECK_AND_RETURN_RET_LOG(format.GetIntValue(MediaDescriptionKey::MD_KEY_WIDTH, width_) &&
225                              width_ >= VIDEO_MIN_SIZE && width_ <= VIDEO_MAX_WIDTH_SIZE,
226                              AVCS_ERR_INVALID_VAL, "Invalid width %{public}d!", width_);
227     CHECK_AND_RETURN_RET_LOG(format.GetIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, height_) &&
228                              height_ >= VIDEO_MIN_SIZE && height_ <= VIDEO_MAX_HEIGHT_SIZE,
229                              AVCS_ERR_INVALID_VAL, "Invalid height %{public}d!", height_);
230     format_.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE,
231                         outputPixelFmt_ == VideoPixelFormat::RGBA ? width_ * VIDEO_PIX_DEPTH_RGBA : width_);
232     format_.PutIntValue(OHOS::Media::Tag::VIDEO_SLICE_HEIGHT, height_);
233     format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_WIDTH, width_);
234     format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_HEIGHT, height_);
235 
236     avCodecContext_->width = width_;
237     avCodecContext_->height = height_;
238     avCodecContext_->thread_count = DEFAULT_THREAD_COUNT;
239 #ifdef SUPPORT_CODEC_RV
240     return SetCodecExtradata(format);
241 #else
242     return AVCS_ERR_OK;
243 #endif
244 }
245 
246 #ifdef SUPPORT_CODEC_RV
SetCodecExtradata(const Format & format)247 int32_t FCodec::SetCodecExtradata(const Format &format)
248 {
249     size_t extraSize = 0;
250     uint8_t *extraData = nullptr;
251     if (format.GetBuffer(MediaDescriptionKey::MD_KEY_CODEC_CONFIG, &extraData, extraSize)) {
252         if (extraData == nullptr || extraSize == 0) {
253             AVCODEC_LOGE("extradata getBufer failed!");
254             return AVCS_ERR_INVALID_VAL;
255         }
256         avCodecContext_->extradata = static_cast<uint8_t *>(av_mallocz(extraSize + AV_INPUT_BUFFER_PADDING_SIZE));
257         if (avCodecContext_->extradata == nullptr) {
258             AVCODEC_LOGE("extradata malloc failed!");
259             return AVCS_ERR_INVALID_VAL;
260         }
261         avCodecContext_->extradata_size = static_cast<int>(extraSize);
262         errno_t rc = memcpy_s(avCodecContext_->extradata, extraSize, extraData, extraSize);
263         if (rc != EOK) {
264             AVCODEC_LOGE("extradata memcpy_s failed.");
265             return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
266         }
267         rc = memset_s(avCodecContext_->extradata + extraSize, AV_INPUT_BUFFER_PADDING_SIZE, 0,
268                       AV_INPUT_BUFFER_PADDING_SIZE);
269         if (rc != EOK) {
270             AVCODEC_LOGE("extradata memset_s failed.");
271             return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
272         }
273     }
274     return AVCS_ERR_OK;
275 }
276 #endif
277 
Configure(const Format & format)278 int32_t FCodec::Configure(const Format &format)
279 {
280     AVCODEC_SYNC_TRACE;
281     if (state_ == State::UNINITIALIZED) {
282         int32_t ret = Initialize();
283         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Init codec failed");
284     }
285     CHECK_AND_RETURN_RET_LOG((state_ == State::INITIALIZED), AVCS_ERR_INVALID_STATE,
286                              "Configure codec failed: not in Initialized state");
287     format_.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_VIDEO_WIDTH);
288     format_.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_VIDEO_HEIGHT);
289     format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, DEFAULT_OUT_BUFFER_CNT);
290     format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, DEFAULT_IN_BUFFER_CNT);
291     for (auto &it : format.GetFormatMap()) {
292         if (it.first == MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT) {
293             isOutBufSetted_ = true;
294             ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
295         } else if (it.first == MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT) {
296             ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
297         } else if (it.first == MediaDescriptionKey::MD_KEY_WIDTH) {
298             ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_WIDTH_SIZE);
299         } else if (it.first == MediaDescriptionKey::MD_KEY_HEIGHT) {
300             ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_HEIGHT_SIZE);
301         } else if (it.first == MediaDescriptionKey::MD_KEY_BITRATE) {
302             int64_t val64 = 0L;
303             CHECK_AND_RETURN_RET_LOG(format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64) && val64 > 0L,
304                                      AVCS_ERR_INVALID_VAL, "Cannot get bit rate!");
305             format_.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64);
306         } else if (it.first == MediaDescriptionKey::MD_KEY_FRAME_RATE) {
307             double val = 0;
308             CHECK_AND_RETURN_RET_LOG(format.GetDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val) && val > 0.0f,
309                                      AVCS_ERR_INVALID_VAL, "Cannot get frame rate!");
310             format_.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val);
311         } else if (it.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT ||
312                    it.first == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE ||
313                    it.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
314             ConfigureSurface(format, it.first, it.second.type);
315         } else {
316             AVCODEC_LOGW("Set parameter failed: %{public}s, unsupport key", it.first.data());
317         }
318     }
319     AVCODEC_LOGI("current pixel format %{public}d", static_cast<int32_t>(outputPixelFmt_));
320     int32_t ret = ConfigureContext(format);
321 
322     state_ = State::CONFIGURED;
323     AVCODEC_LOGI("Configured codec successful: state: Initialized -> Configured");
324     return ret;
325 }
326 
IsActive() const327 bool FCodec::IsActive() const
328 {
329     return state_ == State::RUNNING || state_ == State::FLUSHED || state_ == State::EOS;
330 }
331 
ResetContext(bool isFlush)332 void FCodec::ResetContext(bool isFlush)
333 {
334     CHECK_AND_RETURN_LOG(avCodecContext_ != nullptr, "Avcodec context is nullptr");
335     if (avCodecContext_->extradata) {
336         av_free(avCodecContext_->extradata);
337         avCodecContext_->extradata = nullptr;
338     }
339     avCodecContext_->coded_width = 0;
340     avCodecContext_->coded_height = 0;
341     avCodecContext_->extradata_size = 0;
342     if (!isFlush) {
343         avCodecContext_->width = 0;
344         avCodecContext_->height = 0;
345         avCodecContext_->get_buffer2 = nullptr;
346     }
347 }
348 
Start()349 int32_t FCodec::Start()
350 {
351     AVCODEC_SYNC_TRACE;
352     CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Start codec failed: callback is null");
353     CHECK_AND_RETURN_RET_LOG((state_ == State::CONFIGURED || state_ == State::FLUSHED), AVCS_ERR_INVALID_STATE,
354                              "Start codec failed: not in Configured or Flushed state");
355     if (state_ != State::FLUSHED) {
356         CHECK_AND_RETURN_RET_LOG(avcodec_open2(avCodecContext_.get(), avCodec_.get(), nullptr) == 0, AVCS_ERR_UNKNOWN,
357                                  "Start codec failed: cannot open avcodec");
358     }
359     if (!isBufferAllocated_) {
360         cachedFrame_ = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame *p) { av_frame_free(&p); });
361         avPacket_ = std::shared_ptr<AVPacket>(av_packet_alloc(), [](AVPacket *p) { av_packet_free(&p); });
362         CHECK_AND_RETURN_RET_LOG((cachedFrame_ != nullptr && avPacket_ != nullptr), AVCS_ERR_UNKNOWN,
363                                  "Start codec failed: cannot allocate frame or packet");
364         for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
365             scaleData_[i] = nullptr;
366             scaleLineSize_[i] = 0;
367         }
368         isConverted_ = false;
369         int32_t ret = AllocateBuffers();
370         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Start codec failed: cannot allocate buffers");
371         isBufferAllocated_ = true;
372     }
373     state_ = State::RUNNING;
374     InitBuffers();
375     isSendEos_ = false;
376     sendTask_->Start();
377     receiveTask_->Start();
378     AVCODEC_LOGI("Start codec successful, state: Running");
379     return AVCS_ERR_OK;
380 }
381 
InitBuffers()382 void FCodec::InitBuffers()
383 {
384     inputAvailQue_->SetActive(true);
385     codecAvailQue_->SetActive(true);
386     if (sInfo_.surface != nullptr) {
387         renderAvailQue_->SetActive(true);
388         requestSurfaceBufferQue_->SetActive(true);
389     }
390     CHECK_AND_RETURN_LOG(buffers_[INDEX_INPUT].size() > 0, "Input buffer is null!");
391     for (uint32_t i = 0u; i < buffers_[INDEX_INPUT].size(); i++) {
392         buffers_[INDEX_INPUT][i]->owner_ = Owner::OWNED_BY_USER;
393         callback_->OnInputBufferAvailable(i, buffers_[INDEX_INPUT][i]->avBuffer_);
394         AVCODEC_LOGI("OnInputBufferAvailable frame index = %{public}u, owner = %{public}d", i,
395                      buffers_[INDEX_INPUT][i]->owner_.load());
396     }
397     CHECK_AND_RETURN_LOG(buffers_[INDEX_OUTPUT].size() > 0, "Output buffer is null!");
398     if (sInfo_.surface == nullptr) {
399         for (uint32_t i = 0u; i < buffers_[INDEX_OUTPUT].size(); i++) {
400             buffers_[INDEX_OUTPUT][i]->owner_ = Owner::OWNED_BY_CODEC;
401             codecAvailQue_->Push(i);
402         }
403         return;
404     }
405     for (uint32_t i = 0u; i < buffers_[INDEX_OUTPUT].size(); i++) {
406         std::shared_ptr<FSurfaceMemory> surfaceMemory = buffers_[INDEX_OUTPUT][i]->sMemory_;
407         if (surfaceMemory->isAttached && surfaceMemory->owner == Owner::OWNED_BY_SURFACE) {
408             buffers_[INDEX_OUTPUT][i]->owner_ = Owner::OWNED_BY_SURFACE;
409             renderAvailQue_->Push(i);
410         } else {
411             buffers_[INDEX_OUTPUT][i]->owner_ = Owner::OWNED_BY_CODEC;
412             codecAvailQue_->Push(i);
413         }
414     }
415 }
416 
ResetData()417 void FCodec::ResetData()
418 {
419     if (scaleData_[0] != nullptr) {
420         if (isConverted_) {
421             av_free(scaleData_[0]);
422             isConverted_ = false;
423             scale_.reset();
424         }
425         for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
426             scaleData_[i] = nullptr;
427             scaleLineSize_[i] = 0;
428         }
429     }
430 }
431 
ResetBuffers()432 void FCodec::ResetBuffers()
433 {
434     inputAvailQue_->Clear();
435     std::unique_lock<std::mutex> iLock(inputMutex_);
436     synIndex_ = std::nullopt;
437     iLock.unlock();
438     codecAvailQue_->Clear();
439     if (sInfo_.surface != nullptr) {
440         renderAvailQue_->Clear();
441         requestSurfaceBufferQue_->Clear();
442         renderSurfaceBufferMap_.clear();
443     }
444     ResetData();
445     av_frame_unref(cachedFrame_.get());
446     av_packet_unref(avPacket_.get());
447 }
448 
StopThread()449 void FCodec::StopThread()
450 {
451     if (sendTask_ != nullptr && inputAvailQue_ != nullptr) {
452         std::unique_lock<std::mutex> sLock(sendMutex_);
453         sendCv_.notify_one();
454         sLock.unlock();
455         inputAvailQue_->SetActive(false, false);
456         sendTask_->Stop();
457     }
458     if (receiveTask_ != nullptr && codecAvailQue_ != nullptr) {
459         std::unique_lock<std::mutex> rLock(recvMutex_);
460         recvCv_.notify_one();
461         rLock.unlock();
462         codecAvailQue_->SetActive(false, false);
463         receiveTask_->Stop();
464     }
465     if (sInfo_.surface != nullptr) {
466         if (renderAvailQue_ != nullptr) {
467             renderAvailQue_->SetActive(false, false);
468         }
469         if (requestSurfaceBufferQue_ != nullptr) {
470             requestSurfaceBufferQue_->SetActive(false, false);
471         }
472     }
473 }
474 
Stop()475 int32_t FCodec::Stop()
476 {
477     AVCODEC_SYNC_TRACE;
478     CHECK_AND_RETURN_RET_LOG((IsActive()), AVCS_ERR_INVALID_STATE, "Stop codec failed: not in executing state");
479     state_ = State::STOPPING;
480     AVCODEC_LOGI("step into STOPPING status");
481     std::unique_lock<std::mutex> sLock(sendMutex_);
482     sendCv_.notify_one();
483     sLock.unlock();
484     inputAvailQue_->SetActive(false, false);
485     sendTask_->Stop();
486 
487     if (sInfo_.surface != nullptr) {
488         renderAvailQue_->SetActive(false, false);
489         requestSurfaceBufferQue_->SetActive(false, false);
490     }
491     std::unique_lock<std::mutex> rLock(recvMutex_);
492     recvCv_.notify_one();
493     rLock.unlock();
494     codecAvailQue_->SetActive(false, false);
495     receiveTask_->Stop();
496     avcodec_close(avCodecContext_.get());
497     ResetContext(true);
498     ReleaseBuffers();
499     state_ = State::CONFIGURED;
500     AVCODEC_LOGI("Stop codec successful, state: Configured");
501     return AVCS_ERR_OK;
502 }
503 
Flush()504 int32_t FCodec::Flush()
505 {
506     AVCODEC_SYNC_TRACE;
507     CHECK_AND_RETURN_RET_LOG((state_ == State::RUNNING || state_ == State::EOS), AVCS_ERR_INVALID_STATE,
508                              "Flush codec failed: not in running or Eos state");
509     state_ = State::FLUSHING;
510     AVCODEC_LOGI("step into FLUSHING status");
511     std::unique_lock<std::mutex> sLock(sendMutex_);
512     sendCv_.notify_one();
513     sLock.unlock();
514     inputAvailQue_->SetActive(false, false);
515     sendTask_->Pause();
516 
517     if (sInfo_.surface != nullptr) {
518         renderAvailQue_->SetActive(false, false);
519         requestSurfaceBufferQue_->SetActive(false, false);
520     }
521     std::unique_lock<std::mutex> rLock(recvMutex_);
522     recvCv_.notify_one();
523     rLock.unlock();
524     codecAvailQue_->SetActive(false, false);
525     receiveTask_->Pause();
526 
527     avcodec_flush_buffers(avCodecContext_.get());
528     ResetContext(true);
529     ResetBuffers();
530     state_ = State::FLUSHED;
531     AVCODEC_LOGI("Flush codec successful, state: Flushed");
532     return AVCS_ERR_OK;
533 }
534 
Reset()535 int32_t FCodec::Reset()
536 {
537     AVCODEC_SYNC_TRACE;
538     AVCODEC_LOGI("Reset codec called");
539     int32_t ret = Release();
540     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot release codec");
541     ret = Initialize();
542     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot init codec");
543     AVCODEC_LOGI("Reset codec successful, state: Initialized");
544     return AVCS_ERR_OK;
545 }
546 
ReleaseResource()547 void FCodec::ReleaseResource()
548 {
549     StopThread();
550     if (avCodecContext_ != nullptr) {
551         avcodec_close(avCodecContext_.get());
552         ResetContext();
553     }
554     ReleaseBuffers();
555     format_ = Format();
556     CHECK_AND_RETURN_LOG(sInfo_.surface != nullptr, "Surface is nullptr!");
557     int32_t ret = UnRegisterListenerToSurface(sInfo_.surface);
558     sInfo_.surface = nullptr;
559     StopRequestSurfaceBufferThread();
560     CHECK_AND_RETURN_LOGD(ret != 0, "Unregister surface successful!");
561     callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
562     state_ = State::ERROR;
563 }
564 
Release()565 int32_t FCodec::Release()
566 {
567     AVCODEC_SYNC_TRACE;
568     state_ = State::STOPPING;
569     AVCODEC_LOGI("step into STOPPING status");
570     ReleaseResource();
571     state_ = State::UNINITIALIZED;
572     AVCODEC_LOGI("Release codec successful, state: Uninitialized");
573     return AVCS_ERR_OK;
574 }
575 
SetSurfaceParameter(const Format & format,const std::string_view & formatKey,FormatDataType formatType)576 void FCodec::SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType)
577 {
578     CHECK_AND_RETURN_LOG(formatType == FORMAT_TYPE_INT32, "Set parameter failed: type should be int32");
579     int32_t val = 0;
580     CHECK_AND_RETURN_LOG(format.GetIntValue(formatKey, val), "Set parameter failed: get value fail");
581     if (formatKey == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
582         VideoPixelFormat vpf = static_cast<VideoPixelFormat>(val);
583         CHECK_AND_RETURN_LOG(vpf == VideoPixelFormat::RGBA || vpf == VideoPixelFormat::YUVI420 ||
584                              vpf == VideoPixelFormat::NV12 || vpf == VideoPixelFormat::NV21,
585                              "Set parameter failed: pixel format value %{public}d invalid", val);
586         outputPixelFmt_ = vpf;
587         {
588             std::lock_guard<std::mutex> lock(formatMutex_);
589             format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, val);
590         }
591         GraphicPixelFormat surfacePixelFmt = TranslateSurfaceFormat(vpf);
592         std::lock_guard<std::mutex> sLock(surfaceMutex_);
593         sInfo_.requestConfig.format = surfacePixelFmt;
594     } else if (formatKey == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE) {
595         VideoRotation sr = static_cast<VideoRotation>(val);
596         CHECK_AND_RETURN_LOG(sr == VideoRotation::VIDEO_ROTATION_0 || sr == VideoRotation::VIDEO_ROTATION_90 ||
597                              sr == VideoRotation::VIDEO_ROTATION_180 || sr == VideoRotation::VIDEO_ROTATION_270,
598                              "Set parameter failed: rotation angle value %{public}d invalid", val);
599         {
600             std::lock_guard<std::mutex> lock(formatMutex_);
601             format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val);
602         }
603         std::lock_guard<std::mutex> sLock(surfaceMutex_);
604         sInfo_.surface->SetTransform(TranslateSurfaceRotation(sr));
605     } else {
606         ScalingMode scaleMode = static_cast<ScalingMode>(val);
607         CHECK_AND_RETURN_LOG(scaleMode == ScalingMode::SCALING_MODE_SCALE_TO_WINDOW ||
608                              scaleMode == ScalingMode::SCALING_MODE_SCALE_CROP,
609                              "Set parameter failed: scale type value %{public}d invalid", val);
610         {
611             std::lock_guard<std::mutex> lock(formatMutex_);
612             format_.PutIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, val);
613         }
614         std::lock_guard<std::mutex> sLock(surfaceMutex_);
615         sInfo_.scalingMode = scaleMode;
616     }
617     AVCODEC_LOGI("Set parameter %{public}s success, val %{public}d", std::string(formatKey).c_str(), val);
618 }
619 
SetParameter(const Format & format)620 int32_t FCodec::SetParameter(const Format &format)
621 {
622     AVCODEC_SYNC_TRACE;
623     for (auto &it : format.GetFormatMap()) {
624         if (sInfo_.surface != nullptr && it.second.type == FORMAT_TYPE_INT32) {
625             if (it.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT ||
626                 it.first == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE ||
627                 it.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
628                 SetSurfaceParameter(format, it.first, it.second.type);
629             }
630         } else {
631             AVCODEC_LOGW("Current Version, %{public}s is not supported", it.first.data());
632         }
633     }
634     AVCODEC_LOGI("Set parameter successful");
635     return AVCS_ERR_OK;
636 }
637 
GetOutputFormat(Format & format)638 int32_t FCodec::GetOutputFormat(Format &format)
639 {
640     AVCODEC_SYNC_TRACE;
641     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_BITRATE)) {
642         if (avCodecContext_ != nullptr) {
643             std::lock_guard<std::mutex> lock(formatMutex_);
644             format_.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, avCodecContext_->bit_rate);
645         }
646     }
647     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_FRAME_RATE)) {
648         if (avCodecContext_ != nullptr && avCodecContext_->framerate.den > 0) {
649             double value = static_cast<double>(avCodecContext_->framerate.num) /
650                            static_cast<double>(avCodecContext_->framerate.den);
651             std::lock_guard<std::mutex> lock(formatMutex_);
652             format_.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, value);
653         }
654     }
655     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE)) {
656         int32_t stride = AlignUp(width_, VIDEO_ALIGN_SIZE);
657         int32_t maxInputSize = static_cast<int32_t>((stride * height_ * VIDEO_PIX_DEPTH_YUV) / UV_SCALE_FACTOR);
658         std::lock_guard<std::mutex> lock(formatMutex_);
659         format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, maxInputSize);
660     }
661     {
662         std::lock_guard<std::mutex> lock(formatMutex_);
663         format = format_;
664     }
665     AVCODEC_LOGI("Get outputFormat successful");
666     return AVCS_ERR_OK;
667 }
668 
CalculateBufferSize()669 void FCodec::CalculateBufferSize()
670 {
671     int32_t stride = AlignUp(width_, VIDEO_ALIGN_SIZE);
672     outputBufferSize_ = static_cast<int32_t>((stride * height_ * VIDEO_PIX_DEPTH_YUV) / UV_SCALE_FACTOR);
673     inputBufferSize_ = std::max(VIDEO_MIN_BUFFER_SIZE, outputBufferSize_);
674     if (outputPixelFmt_ == VideoPixelFormat::RGBA) {
675         outputBufferSize_ = static_cast<int32_t>(stride * height_ * VIDEO_PIX_DEPTH_RGBA);
676     }
677     AVCODEC_LOGI("width = %{public}d, height = %{public}d, stride = %{public}d, Input buffer size = %{public}d, output "
678                  "buffer size=%{public}d",
679                  width_, height_, stride, inputBufferSize_, outputBufferSize_);
680 }
681 
AllocateInputBuffer(int32_t bufferCnt,int32_t inBufferSize)682 int32_t FCodec::AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize)
683 {
684     int32_t valBufferCnt = 0;
685     for (int32_t i = 0; i < bufferCnt; i++) {
686         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
687         std::shared_ptr<AVAllocator> allocator =
688             AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
689         CHECK_AND_CONTINUE_LOG(allocator != nullptr, "input buffer %{public}d allocator is nullptr", i);
690         buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, inBufferSize);
691         CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr && buf->avBuffer_->memory_ != nullptr,
692                                "Allocate input buffer failed, index=%{public}d", i);
693         AVCODEC_LOGI("Allocate input buffer success: index=%{public}d, size=%{public}d",
694                      i, buf->avBuffer_->memory_->GetCapacity());
695         buffers_[INDEX_INPUT].emplace_back(buf);
696         valBufferCnt++;
697     }
698     CHECK_AND_RETURN_RET_LOGD(valBufferCnt < DEFAULT_MIN_BUFFER_CNT, AVCS_ERR_OK, "Allocate input buffers successful");
699     AVCODEC_LOGE("Allocate input buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
700     buffers_[INDEX_INPUT].clear();
701     return AVCS_ERR_NO_MEMORY;
702 }
703 
SetSurfaceCfg()704 int32_t FCodec::SetSurfaceCfg()
705 {
706     if (outputPixelFmt_ == VideoPixelFormat::UNKNOWN) {
707         format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
708     }
709     int32_t val32 = 0;
710     format_.GetIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, val32);
711     GraphicPixelFormat surfacePixelFmt = TranslateSurfaceFormat(static_cast<VideoPixelFormat>(val32));
712     CHECK_AND_RETURN_RET_LOG(surfacePixelFmt != GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BUTT, AVCS_ERR_UNSUPPORT,
713                              "Failed to allocate output buffer: unsupported surface format");
714     sInfo_.requestConfig.width = width_;
715     sInfo_.requestConfig.height = height_;
716     sInfo_.requestConfig.format = surfacePixelFmt;
717 
718     CHECK_AND_RETURN_RET_LOG(format_.GetIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, val32) && val32 >= 0 &&
719                              val32 <= static_cast<int32_t>(ScalingMode::SCALING_MODE_SCALE_FIT),
720                              AVCS_ERR_INVALID_VAL, "Invalid scaling mode %{public}d", val32);
721     sInfo_.scalingMode = static_cast<ScalingMode>(val32);
722     CHECK_AND_RETURN_RET_LOG(format_.GetIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val32) && val32 >= 0 &&
723                              val32 <= static_cast<int32_t>(VideoRotation::VIDEO_ROTATION_270), AVCS_ERR_INVALID_VAL,
724                              "Invalid rotation angle %{public}d", val32);
725     sInfo_.surface->SetTransform(TranslateSurfaceRotation(static_cast<VideoRotation>(val32)));
726     return AVCS_ERR_OK;
727 }
728 
RequestSurfaceBufferThread()729 void FCodec::RequestSurfaceBufferThread()
730 {
731     while (!requestBufferThreadExit_.load()) {
732         std::unique_lock<std::mutex> lck(requestBufferMutex_);
733         requestBufferCV_.wait(lck, [this]() {
734             return requestBufferThreadExit_.load() || !requestBufferFinished_.load();
735         });
736         if (requestBufferThreadExit_.load()) {
737             requestBufferFinished_ = true;
738             requestBufferOnceDoneCV_.notify_one();
739             break;
740         }
741         auto index = requestSurfaceBufferQue_->Front();
742         requestSurfaceBufferQue_->Pop();
743         std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
744         std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
745         sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
746         if (surfaceBuffer == nullptr) {
747             AVCODEC_LOGE("Get surface buffer failed, index=%{public}u", index);
748         }
749         requestBufferFinished_ = true;
750         requestBufferOnceDoneCV_.notify_one();
751     }
752     AVCODEC_LOGI("RequestSurfaceBufferThread exit.");
753 }
754 
StartRequestSurfaceBufferThread()755 void FCodec::StartRequestSurfaceBufferThread()
756 {
757     if (!mRequestSurfaceBufferThread_.joinable()) {
758         requestBufferThreadExit_ = false;
759         requestBufferFinished_ = true;
760         mRequestSurfaceBufferThread_ = std::thread(&FCodec::RequestSurfaceBufferThread, this);
761     }
762 }
763 
StopRequestSurfaceBufferThread()764 void FCodec::StopRequestSurfaceBufferThread()
765 {
766     if (mRequestSurfaceBufferThread_.joinable()) {
767         requestBufferThreadExit_ = true;
768         requestBufferFinished_ = false;
769         requestBufferCV_.notify_all();
770         requestBufferFinished_ = true;
771         requestBufferOnceDoneCV_.notify_all();
772         mRequestSurfaceBufferThread_.join();
773     }
774 }
775 
RequestSurfaceBufferOnce(uint32_t index)776 bool FCodec::RequestSurfaceBufferOnce(uint32_t index)
777 {
778     if (!requestBufferThreadExit_.load()) {
779         std::unique_lock<std::mutex> lck(requestBufferMutex_);
780         requestBufferFinished_ = false;
781         requestSurfaceBufferQue_->Push(index);
782         requestBufferCV_.notify_one();
783         requestBufferOnceDoneCV_.wait(lck, [this]() { return requestBufferFinished_.load(); });
784         std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
785         std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
786         if (surfaceMemory == nullptr || surfaceMemory->GetBase() == nullptr) {
787             AVCODEC_LOGE("Output surface memory %{public}u allocate failed", index);
788             return false;
789         }
790         return true;
791     }
792     return false;
793 }
794 
AllocateOutputBuffer(int32_t bufferCnt,int32_t outBufferSize)795 int32_t FCodec::AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize)
796 {
797     CHECK_AND_RETURN_RET_LOG(sInfo_.surface == nullptr, AVCS_ERR_UNKNOWN, "Not in buffer mode!");
798     int32_t valBufferCnt = 0;
799     for (int i = 0; i < bufferCnt; i++) {
800         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
801         buf->width_ = width_;
802         buf->height_ = height_;
803         std::shared_ptr<AVAllocator> allocator =
804             AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
805         CHECK_AND_CONTINUE_LOG(allocator != nullptr, "Output buffer %{public}d allocator is nullptr!", i);
806         buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, outBufferSize);
807         CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr && buf->avBuffer_->memory_ != nullptr,
808                                "Allocate output buffer failed, index=%{public}d", i);
809         AVCODEC_LOGI("Allocate output share buffer success: index=%{public}d, size=%{public}d", i,
810                      buf->avBuffer_->memory_->GetCapacity());
811         CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr, "Allocate output buffer failed, index=%{public}d", i);
812         buffers_[INDEX_OUTPUT].emplace_back(buf);
813         valBufferCnt++;
814     }
815     CHECK_AND_RETURN_RET_LOGD(valBufferCnt < DEFAULT_MIN_BUFFER_CNT, AVCS_ERR_OK, "Allocate output buffers successful");
816     AVCODEC_LOGE("Allocate output buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
817     buffers_[INDEX_INPUT].clear();
818     buffers_[INDEX_OUTPUT].clear();
819     return AVCS_ERR_NO_MEMORY;
820 }
821 
ClearSurfaceAndSetQueueSize(const sptr<Surface> & surface,int32_t bufferCnt)822 int32_t FCodec::ClearSurfaceAndSetQueueSize(const sptr<Surface> &surface, int32_t bufferCnt)
823 {
824     surface->Connect();
825     surface->CleanCache(); // clean cache will work only if the surface is connected by us.
826     int32_t ret = SetQueueSize(surface, bufferCnt);
827     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Set surface queue size failed!");
828     ret = SetSurfaceCfg();
829     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Set surface cfg failed!");
830     CHECK_AND_RETURN_RET_LOGD(buffers_[INDEX_OUTPUT].size() > 0u, AVCS_ERR_OK, "Set surface cfg & queue size success.");
831     int32_t valBufferCnt = 0;
832     for (auto &it : buffers_[INDEX_OUTPUT]) {
833         std::shared_ptr<FSurfaceMemory> surfaceMemory = it->sMemory_;
834         surfaceMemory->isAttached = false;
835         valBufferCnt++;
836     }
837     CHECK_AND_RETURN_RET_LOG(valBufferCnt == bufferCnt, AVCS_ERR_UNKNOWN, "Outbuf cnt(%{public}d) != %{public}d",
838                              valBufferCnt, bufferCnt);
839     return AVCS_ERR_OK;
840 }
841 
AllocateOutputBuffersFromSurface(int32_t bufferCnt)842 int32_t FCodec::AllocateOutputBuffersFromSurface(int32_t bufferCnt)
843 {
844     CHECK_AND_RETURN_RET_LOG(sInfo_.surface != nullptr, AVCS_ERR_UNKNOWN, "Not in surface mode!");
845     int32_t ret = ClearSurfaceAndSetQueueSize(sInfo_.surface, bufferCnt);
846     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Clean surface and set queue size failed!");
847     requestSurfaceBufferQue_->Clear();
848     requestSurfaceBufferQue_->SetActive(true);
849     StartRequestSurfaceBufferThread();
850     for (int32_t i = 0; i < bufferCnt; i++) {
851         std::shared_ptr<FSurfaceMemory> surfaceMemory = std::make_shared<FSurfaceMemory>(&sInfo_);
852         CHECK_AND_RETURN_RET_LOG(surfaceMemory != nullptr, AVCS_ERR_UNKNOWN, "Creata surface memory failed!");
853         ret = surfaceMemory->AllocSurfaceBuffer();
854         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Alloc surface buffer failed!");
855         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
856         CHECK_AND_RETURN_RET_LOG(buf != nullptr, AVCS_ERR_UNKNOWN, "Creata output buffer failed!");
857         buf->sMemory_ = surfaceMemory;
858         buf->height_ = height_;
859         buf->width_ = width_;
860         outAVBuffer4Surface_.emplace_back(AVBuffer::CreateAVBuffer());
861         buf->avBuffer_ = AVBuffer::CreateAVBuffer(buf->sMemory_->GetBase(), buf->sMemory_->GetSize());
862         AVCODEC_LOGI("Allocate output surface buffer success, index=%{public}d, size=%{public}d, stride=%{public}d", i,
863                      buf->sMemory_->GetSize(), buf->sMemory_->GetSurfaceBufferStride());
864         buffers_[INDEX_OUTPUT].emplace_back(buf);
865     }
866     int32_t outputBufferNum = static_cast<int32_t>(buffers_[INDEX_OUTPUT].size());
867     CHECK_AND_RETURN_RET_LOG(outputBufferNum == bufferCnt, AVCS_ERR_UNKNOWN,
868                              "Only alloc %{public}d buffers, less %{public}d", outputBufferNum, bufferCnt);
869     return AVCS_ERR_OK;
870 }
871 
AllocateBuffers()872 int32_t FCodec::AllocateBuffers()
873 {
874     AVCODEC_SYNC_TRACE;
875     CalculateBufferSize();
876     CHECK_AND_RETURN_RET_LOG(inputBufferSize_ > 0 && outputBufferSize_ > 0, AVCS_ERR_INVALID_VAL,
877                              "Allocate buffer with input size=%{public}d, output size=%{public}d failed",
878                              inputBufferSize_, outputBufferSize_);
879     if (sInfo_.surface != nullptr && isOutBufSetted_ == false) {
880         format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, DEFAULT_OUT_SURFACE_CNT);
881     }
882     CHECK_AND_RETURN_RET_LOG(
883         format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, inputBufferCnt_) &&
884         inputBufferCnt_ >= DEFAULT_MIN_BUFFER_CNT, AVCS_ERR_INVALID_VAL,
885         "Invalid input buffer cnt: %{public}d", inputBufferCnt_);
886     CHECK_AND_RETURN_RET_LOG(
887         format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, outputBufferCnt_) &&
888         outputBufferCnt_ >= DEFAULT_MIN_BUFFER_CNT, AVCS_ERR_INVALID_VAL,
889         "Invalid output buffer cnt: %{public}d", outputBufferCnt_);
890     inputAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("inputAvailQue", inputBufferCnt_);
891     codecAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("codecAvailQue", outputBufferCnt_);
892     if (sInfo_.surface != nullptr) {
893         renderAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("renderAvailQue", outputBufferCnt_);
894         requestSurfaceBufferQue_ = std::make_shared<BlockQueue<uint32_t>>("requestSurfaceBufferQue", outputBufferCnt_);
895     }
896     int32_t ret = AllocateInputBuffer(inputBufferCnt_, inputBufferSize_);
897     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Allocate input buffers failed!");
898     ret = sInfo_.surface ? AllocateOutputBuffersFromSurface(outputBufferCnt_)
899                          : AllocateOutputBuffer(outputBufferCnt_, outputBufferSize_);
900     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Allocate output buffers failed!");
901     return AVCS_ERR_OK;
902 }
903 
UpdateBuffers(uint32_t index,int32_t bufferSize,uint32_t bufferType)904 int32_t FCodec::UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType)
905 {
906     int32_t curBufSize = buffers_[bufferType][index]->avBuffer_->memory_->GetCapacity();
907     if (bufferSize != curBufSize) {
908         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
909         std::shared_ptr<AVAllocator> allocator =
910             AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
911         CHECK_AND_RETURN_RET_LOG(allocator != nullptr, AVCS_ERR_NO_MEMORY, "buffer %{public}d allocator is nullptr",
912                                  index);
913         buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, bufferSize);
914         CHECK_AND_RETURN_RET_LOG(buf->avBuffer_ != nullptr, AVCS_ERR_NO_MEMORY,
915                                  "Buffer allocate failed, index=%{public}d", index);
916         AVCODEC_LOGI("update share buffer success: bufferType=%{public}u, index=%{public}d, size=%{public}d",
917                      bufferType, index, buf->avBuffer_->memory_->GetCapacity());
918 
919         if (bufferType == INDEX_INPUT) {
920             buf->owner_ = Owner::OWNED_BY_USER;
921         } else {
922             buf->owner_ = Owner::OWNED_BY_CODEC;
923         }
924         buffers_[bufferType][index] = buf;
925     }
926     return AVCS_ERR_OK;
927 }
928 
UpdateSurfaceMemory(uint32_t index)929 int32_t FCodec::UpdateSurfaceMemory(uint32_t index)
930 {
931     AVCODEC_SYNC_TRACE;
932     std::unique_lock<std::mutex> oLock(outputMutex_);
933     std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
934     oLock.unlock();
935     if (width_ != outputBuffer->width_ || height_ != outputBuffer->height_) {
936         std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
937         CHECK_AND_RETURN_RET_LOG(surfaceMemory != nullptr, AVCS_ERR_UNKNOWN, "Surface memory is nullptr!");
938         AVCODEC_LOGI("Update surface memory, width=%{public}d, height=%{public}d", width_, height_);
939         std::lock_guard<std::mutex> sLock(surfaceMutex_);
940         if (surfaceMemory->isAttached) {
941             sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
942             CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, AVCS_ERR_UNKNOWN, "Get surface buffer failed!");
943             int32_t ret = Detach(surfaceBuffer);
944             CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Surface buffer detach failed!");
945             surfaceMemory->isAttached = false;
946         }
947         surfaceMemory->ReleaseSurfaceBuffer();
948         int32_t ret = surfaceMemory->AllocSurfaceBuffer();
949         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Alloc surface buffer failed!");
950         sptr<SurfaceBuffer> newSurfaceBuffer = surfaceMemory->GetSurfaceBuffer();
951         CHECK_AND_RETURN_RET_LOG(newSurfaceBuffer != nullptr, AVCS_ERR_UNKNOWN, "Alloc surface buffer failed!");
952         ret = Attach(newSurfaceBuffer);
953         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Surface buffer attach failed!");
954         surfaceMemory->isAttached = true;
955         outputBuffer->avBuffer_ =
956             AVBuffer::CreateAVBuffer(outputBuffer->sMemory_->GetBase(), outputBuffer->sMemory_->GetSize());
957         outputBuffer->width_ = width_;
958         outputBuffer->height_ = height_;
959     }
960     return AVCS_ERR_OK;
961 }
962 
CheckFormatChange(uint32_t index,int width,int height)963 int32_t FCodec::CheckFormatChange(uint32_t index, int width, int height)
964 {
965     if (width_ != width || height_ != height) {
966         AVCODEC_LOGI("format change, width: %{public}d->%{public}d, height: %{public}d->%{public}d", width_, width,
967                      height_, height);
968         width_ = width;
969         height_ = height;
970         ResetData();
971         scale_ = nullptr;
972         CalculateBufferSize();
973         {
974             std::lock_guard<std::mutex> lock(formatMutex_);
975             format_.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, width_);
976             format_.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, height_);
977             format_.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE,
978                                 outputPixelFmt_ == VideoPixelFormat::RGBA ? width_ * VIDEO_PIX_DEPTH_RGBA : width_);
979             format_.PutIntValue(OHOS::Media::Tag::VIDEO_SLICE_HEIGHT, height_);
980             format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_WIDTH, width_);
981             format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_HEIGHT, height_);
982         }
983         if (sInfo_.surface) {
984             std::lock_guard<std::mutex> sLock(surfaceMutex_);
985             sInfo_.requestConfig.width = width_;
986             sInfo_.requestConfig.height = height_;
987         }
988         callback_->OnOutputFormatChanged(format_);
989     }
990     if (sInfo_.surface == nullptr) {
991         std::lock_guard<std::mutex> oLock(outputMutex_);
992         CHECK_AND_RETURN_RET_LOG((UpdateBuffers(index, outputBufferSize_, INDEX_OUTPUT) == AVCS_ERR_OK),
993                                  AVCS_ERR_NO_MEMORY, "Update  output buffer failed, index=%{public}u", index);
994     } else {
995         CHECK_AND_RETURN_RET_LOG((UpdateSurfaceMemory(index) == AVCS_ERR_OK), AVCS_ERR_NO_MEMORY,
996                                  "Update buffer failed");
997     }
998     return AVCS_ERR_OK;
999 }
1000 
ReleaseBuffers()1001 void FCodec::ReleaseBuffers()
1002 {
1003     ResetData();
1004     if (!isBufferAllocated_) {
1005         return;
1006     }
1007 
1008     inputAvailQue_->Clear();
1009     std::unique_lock<std::mutex> iLock(inputMutex_);
1010     buffers_[INDEX_INPUT].clear();
1011     inputBufferCnt_ = 0;
1012     synIndex_ = std::nullopt;
1013     iLock.unlock();
1014 
1015     std::unique_lock<std::mutex> oLock(outputMutex_);
1016     codecAvailQue_->Clear();
1017     if (sInfo_.surface != nullptr) {
1018         StopRequestSurfaceBufferThread();
1019         renderAvailQue_->Clear();
1020         requestSurfaceBufferQue_->Clear();
1021         renderSurfaceBufferMap_.clear();
1022         for (uint32_t i = 0; i < buffers_[INDEX_OUTPUT].size(); i++) {
1023             std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][i];
1024             if (outputBuffer->owner_ == Owner::OWNED_BY_CODEC) {
1025                 std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
1026                 surfaceMemory->ReleaseSurfaceBuffer();
1027                 outputBuffer->owner_ = Owner::OWNED_BY_SURFACE;
1028             }
1029         }
1030         sInfo_.surface->CleanCache();
1031         AVCODEC_LOGI("surface cleancache success");
1032     }
1033     buffers_[INDEX_OUTPUT].clear();
1034     outAVBuffer4Surface_.clear();
1035     outputBufferCnt_ = 0;
1036     oLock.unlock();
1037     isBufferAllocated_ = false;
1038 }
1039 
QueueInputBuffer(uint32_t index)1040 int32_t FCodec::QueueInputBuffer(uint32_t index)
1041 {
1042     AVCODEC_SYNC_TRACE;
1043     CHECK_AND_RETURN_RET_LOG(state_ == State::RUNNING, AVCS_ERR_INVALID_STATE,
1044                              "Queue input buffer failed: not in Running state");
1045     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_INPUT].size(), AVCS_ERR_INVALID_VAL,
1046                              "Queue input buffer failed with bad index, index=%{public}u, buffer_size=%{public}zu",
1047                              index, buffers_[INDEX_INPUT].size());
1048     std::shared_ptr<FBuffer> inputBuffer = buffers_[INDEX_INPUT][index];
1049     CHECK_AND_RETURN_RET_LOG(inputBuffer->owner_ == Owner::OWNED_BY_USER, AVCS_ERR_INVALID_OPERATION,
1050                              "Queue input buffer failed: buffer with index=%{public}u is not available", index);
1051 
1052     inputBuffer->owner_ = Owner::OWNED_BY_CODEC;
1053     std::shared_ptr<AVBuffer> &inputAVBuffer = inputBuffer->avBuffer_;
1054     if (synIndex_) {
1055         const std::shared_ptr<AVBuffer> &curAVBuffer = buffers_[INDEX_INPUT][synIndex_.value()]->avBuffer_;
1056         int32_t curAVBufferSize = curAVBuffer->memory_->GetSize();
1057         int32_t inputAVBufferSize = inputAVBuffer->memory_->GetSize();
1058         if ((curAVBufferSize + inputAVBufferSize <= curAVBuffer->memory_->GetCapacity()) &&
1059             memcpy_s(curAVBuffer->memory_->GetAddr() + curAVBufferSize, inputAVBufferSize,
1060                      inputAVBuffer->memory_->GetAddr(), inputAVBufferSize) == EOK) {
1061             curAVBuffer->memory_->SetSize(curAVBufferSize + inputAVBufferSize);
1062             curAVBuffer->flag_ = inputAVBuffer->flag_;
1063             curAVBuffer->pts_ = inputAVBuffer->pts_;
1064 
1065             if (inputAVBuffer->flag_ != AVCODEC_BUFFER_FLAG_CODEC_DATA &&
1066                 inputAVBuffer->flag_ != AVCODEC_BUFFER_FLAG_PARTIAL_FRAME) {
1067                 inputAvailQue_->Push(synIndex_.value());
1068                 synIndex_ = std::nullopt;
1069             }
1070             inputBuffer->owner_ = Owner::OWNED_BY_USER;
1071             callback_->OnInputBufferAvailable(index, inputAVBuffer);
1072             return AVCS_ERR_OK;
1073         } else {
1074             AVCODEC_LOGE("packet size %{public}d over buffer size %{public}d", curAVBufferSize + inputAVBufferSize,
1075                          curAVBuffer->memory_->GetCapacity());
1076             callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY);
1077             state_ = State::ERROR;
1078             return AVCS_ERR_NO_MEMORY;
1079         }
1080     } else {
1081         if ((inputAVBuffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) ||
1082             (inputAVBuffer->flag_ == AVCODEC_BUFFER_FLAG_PARTIAL_FRAME)) {
1083             synIndex_ = index;
1084         } else {
1085             inputAvailQue_->Push(index);
1086         }
1087     }
1088 
1089     return AVCS_ERR_OK;
1090 }
1091 
SendFrame()1092 void FCodec::SendFrame()
1093 {
1094     CHECK_AND_RETURN_LOG(state_ != State::STOPPING && state_ != State::FLUSHING, "Invalid state");
1095     if (state_ != State::RUNNING || isSendEos_) {
1096         std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_DECODE_TIME));
1097         return;
1098     }
1099     uint32_t index = inputAvailQue_->Front();
1100     CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1101     std::shared_ptr<FBuffer> &inputBuffer = buffers_[INDEX_INPUT][index];
1102     std::shared_ptr<AVBuffer> &inputAVBuffer = inputBuffer->avBuffer_;
1103     if (inputAVBuffer->flag_ & AVCODEC_BUFFER_FLAG_EOS) {
1104         avPacket_->data = nullptr;
1105         avPacket_->size = 0;
1106         avPacket_->pts = 0;
1107         std::unique_lock<std::mutex> sendLock(sendMutex_);
1108         isSendEos_ = true;
1109         sendCv_.wait_for(sendLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
1110         AVCODEC_LOGI("Send eos end");
1111     } else {
1112         avPacket_->data = inputAVBuffer->memory_->GetAddr();
1113         avPacket_->size = static_cast<int32_t>(inputAVBuffer->memory_->GetSize());
1114         avPacket_->pts = inputAVBuffer->pts_;
1115     }
1116     std::unique_lock<std::mutex> sLock(syncMutex_);
1117     int ret = avcodec_send_packet(avCodecContext_.get(), avPacket_.get());
1118     sLock.unlock();
1119     if (ret == 0 || ret == AVERROR_INVALIDDATA) {
1120         EXPECT_AND_LOGW(ret == AVERROR_INVALIDDATA, "ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1121         std::unique_lock<std::mutex> recvLock(recvMutex_);
1122         recvCv_.notify_one();
1123         recvLock.unlock();
1124         inputAvailQue_->Pop();
1125         inputBuffer->owner_ = Owner::OWNED_BY_USER;
1126 #ifdef BUILD_ENG_VERSION
1127         if (dumpInFile_ && dumpInFile_->is_open()) {
1128             dumpInFile_->write(reinterpret_cast<char *>(inputAVBuffer->memory_->GetAddr()),
1129                                static_cast<int32_t>(inputAVBuffer->memory_->GetSize()));
1130         }
1131 #endif // BUILD_ENG_VERSION
1132         callback_->OnInputBufferAvailable(index, inputAVBuffer);
1133     } else if (ret == AVERROR(EAGAIN)) {
1134         std::unique_lock<std::mutex> sendLock(sendMutex_);
1135         isSendWait_ = true;
1136         sendCv_.wait_for(sendLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
1137     } else {
1138         AVCODEC_LOGE("Cannot send frame to codec: ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1139         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1140         state_ = State::ERROR;
1141     }
1142 }
1143 
FillFrameBuffer(const std::shared_ptr<FBuffer> & frameBuffer)1144 int32_t FCodec::FillFrameBuffer(const std::shared_ptr<FBuffer> &frameBuffer)
1145 {
1146     VideoPixelFormat targetPixelFmt = outputPixelFmt_;
1147     if (outputPixelFmt_ == VideoPixelFormat::UNKNOWN) {
1148         targetPixelFmt = sInfo_.surface ? VideoPixelFormat::NV12 : ConvertPixelFormatFromFFmpeg(cachedFrame_->format);
1149     }
1150     AVPixelFormat ffmpegFormat = ConvertPixelFormatToFFmpeg(targetPixelFmt);
1151     int32_t ret;
1152     if (ffmpegFormat == static_cast<AVPixelFormat>(cachedFrame_->format)) {
1153         for (int32_t i = 0; i < AV_NUM_DATA_POINTERS && cachedFrame_->linesize[i] > 0; i++) {
1154             scaleData_[i] = cachedFrame_->data[i];
1155             scaleLineSize_[i] = cachedFrame_->linesize[i];
1156         }
1157     } else {
1158         ret = ConvertVideoFrame(&scale_, cachedFrame_, scaleData_, scaleLineSize_, ffmpegFormat);
1159         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Scale video frame failed: %{public}d", ret);
1160         isConverted_ = true;
1161     }
1162     {
1163         std::lock_guard<std::mutex> lock(formatMutex_);
1164         format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(targetPixelFmt));
1165     }
1166     std::shared_ptr<AVMemory> &bufferMemory = frameBuffer->avBuffer_->memory_;
1167     CHECK_AND_RETURN_RET_LOG(bufferMemory != nullptr, AVCS_ERR_INVALID_VAL, "bufferMemory is nullptr");
1168     bufferMemory->SetSize(0);
1169     if (sInfo_.surface) {
1170         struct SurfaceInfo surfaceInfo;
1171         surfaceInfo.surfaceStride = static_cast<uint32_t>(frameBuffer->sMemory_->GetSurfaceBufferStride());
1172         surfaceInfo.surfaceFence = frameBuffer->sMemory_->GetFence();
1173         surfaceInfo.scaleData = scaleData_;
1174         surfaceInfo.scaleLineSize = scaleLineSize_;
1175         ret = WriteSurfaceData(bufferMemory, surfaceInfo, format_);
1176     } else {
1177         ret = WriteBufferData(bufferMemory, scaleData_, scaleLineSize_, format_);
1178     }
1179     frameBuffer->avBuffer_->pts_ = cachedFrame_->pts;
1180     AVCODEC_LOGD("Fill frame buffer successful");
1181     return ret;
1182 }
1183 
FramePostProcess(std::shared_ptr<FBuffer> & frameBuffer,uint32_t index,int32_t status,int ret)1184 void FCodec::FramePostProcess(std::shared_ptr<FBuffer> &frameBuffer, uint32_t index, int32_t status, int ret)
1185 {
1186     if (status == AVCS_ERR_OK) {
1187         codecAvailQue_->Pop();
1188         frameBuffer->owner_ = Owner::OWNED_BY_USER;
1189         if (sInfo_.surface) {
1190             outAVBuffer4Surface_[index]->pts_ = frameBuffer->avBuffer_->pts_;
1191             outAVBuffer4Surface_[index]->flag_ = frameBuffer->avBuffer_->flag_;
1192         }
1193         if (ret == AVERROR_EOF) {
1194             std::unique_lock<std::mutex> sLock(syncMutex_);
1195             avcodec_flush_buffers(avCodecContext_.get());
1196             sLock.unlock();
1197         } else {
1198             if (isSendWait_) {
1199                 std::lock_guard<std::mutex> sLock(sendMutex_);
1200                 isSendWait_ = false;
1201                 sendCv_.notify_one();
1202             }
1203         }
1204         callback_->OnOutputBufferAvailable(index,
1205                                            sInfo_.surface ? outAVBuffer4Surface_[index] : frameBuffer->avBuffer_);
1206     } else if (status == AVCS_ERR_UNSUPPORT) {
1207         AVCODEC_LOGE("Recevie frame from codec failed: OnError");
1208         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT);
1209         state_ = State::ERROR;
1210     } else {
1211         AVCODEC_LOGE("Recevie frame from codec failed");
1212         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1213         state_ = State::ERROR;
1214     }
1215 }
1216 
DumpOutputBuffer()1217 void FCodec::DumpOutputBuffer()
1218 {
1219     AVCODEC_LOGD("cur decNum: %{public}u", decNum_);
1220     if (decNum_ == 0) {
1221         callback_->OnOutputFormatChanged(format_);
1222     }
1223     decNum_++;
1224 #ifdef BUILD_ENG_VERSION
1225     if (!dumpOutFile_ || !dumpOutFile_->is_open()) {
1226         return;
1227     }
1228     for (int32_t i = 0; i < cachedFrame_->height; i++) {
1229         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[0] + i * cachedFrame_->linesize[0]),
1230                             static_cast<int32_t>(cachedFrame_->width));
1231     }
1232     for (int32_t i = 0; i < cachedFrame_->height / 2; i++) { // 2
1233         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[1] + i * cachedFrame_->linesize[1]),
1234                             static_cast<int32_t>(cachedFrame_->width / 2)); // 2
1235     }
1236     for (int32_t i = 0; i < cachedFrame_->height / 2; i++) { // 2
1237         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[2] + i * cachedFrame_->linesize[2]),
1238                             static_cast<int32_t>(cachedFrame_->width / 2)); // 2
1239     }
1240 #endif // BUILD_ENG_VERSION
1241 }
1242 
ReceiveFrame()1243 void FCodec::ReceiveFrame()
1244 {
1245     CHECK_AND_RETURN_LOG(state_ != State::STOPPING && state_ != State::FLUSHING, "Invalid state");
1246     if (state_ != State::RUNNING) {
1247         std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_DECODE_TIME));
1248         return;
1249     }
1250     auto index = codecAvailQue_->Front();
1251     CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1252     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1253     std::unique_lock<std::mutex> sLock(syncMutex_);
1254     int ret = avcodec_receive_frame(avCodecContext_.get(), cachedFrame_.get());
1255     sLock.unlock();
1256     int32_t status = AVCS_ERR_OK;
1257     CHECK_AND_RETURN_LOG(ret != AVERROR_INVALIDDATA, "ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1258     if (ret >= 0) {
1259         DumpOutputBuffer();
1260         if (CheckFormatChange(index, cachedFrame_->width, cachedFrame_->height) == AVCS_ERR_OK) {
1261             CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1262             frameBuffer = buffers_[INDEX_OUTPUT][index];
1263             status = FillFrameBuffer(frameBuffer);
1264         } else {
1265             CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1266             callback_->OnError(AVCODEC_ERROR_EXTEND_START, AVCS_ERR_NO_MEMORY);
1267             return;
1268         }
1269         frameBuffer->avBuffer_->flag_ = AVCODEC_BUFFER_FLAG_NONE;
1270     } else if (ret == AVERROR_EOF) {
1271         AVCODEC_LOGI("Receive eos");
1272         frameBuffer->avBuffer_->flag_ = AVCODEC_BUFFER_FLAG_EOS;
1273         frameBuffer->avBuffer_->memory_->SetSize(0);
1274         state_ = State::EOS;
1275     } else if (ret == AVERROR(EAGAIN)) {
1276         std::unique_lock<std::mutex> sendLock(sendMutex_);
1277         if (isSendWait_ || isSendEos_) {
1278             isSendWait_ = false;
1279             sendCv_.notify_one();
1280         }
1281         sendLock.unlock();
1282         std::unique_lock<std::mutex> recvLock(recvMutex_);
1283         recvCv_.wait_for(recvLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
1284         return;
1285     } else {
1286         AVCODEC_LOGE("Cannot recv frame from codec: ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1287         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1288         state_ = State::ERROR;
1289         return;
1290     }
1291     FramePostProcess(frameBuffer, index, status, ret);
1292 }
1293 
FindAvailIndex(uint32_t index)1294 void FCodec::FindAvailIndex(uint32_t index)
1295 {
1296     uint32_t curQueSize = renderAvailQue_->Size();
1297     for (uint32_t i = 0u; i < curQueSize; i++) {
1298         uint32_t num = renderAvailQue_->Pop();
1299         if (num == index) {
1300             break;
1301         } else {
1302             renderAvailQue_->Push(num);
1303         }
1304     }
1305 }
1306 
ReleaseOutputBuffer(uint32_t index)1307 int32_t FCodec::ReleaseOutputBuffer(uint32_t index)
1308 {
1309     AVCODEC_SYNC_TRACE;
1310     std::unique_lock<std::mutex> oLock(outputMutex_);
1311     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_OUTPUT].size(), AVCS_ERR_INVALID_VAL,
1312                              "Failed to release output buffer: invalid index");
1313     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1314     oLock.unlock();
1315     if (frameBuffer->owner_ == Owner::OWNED_BY_USER) {
1316         frameBuffer->owner_ = Owner::OWNED_BY_CODEC;
1317         codecAvailQue_->Push(index);
1318         return AVCS_ERR_OK;
1319     } else {
1320         AVCODEC_LOGE("Release output buffer failed: check your index=%{public}u", index);
1321         return AVCS_ERR_INVALID_VAL;
1322     }
1323 }
1324 
Attach(sptr<SurfaceBuffer> surfaceBuffer)1325 int32_t FCodec::Attach(sptr<SurfaceBuffer> surfaceBuffer)
1326 {
1327     int32_t err = sInfo_.surface->AttachBufferToQueue(surfaceBuffer);
1328     CHECK_AND_RETURN_RET_LOG(
1329         err == 0, err, "Surface(%{public}" PRIu64 "), attach buffer(%{public}u) to queue failed, GSError=%{public}d",
1330         sInfo_.surface->GetUniqueId(), surfaceBuffer->GetSeqNum(), err);
1331     return AVCS_ERR_OK;
1332 }
1333 
Detach(sptr<SurfaceBuffer> surfaceBuffer)1334 int32_t FCodec::Detach(sptr<SurfaceBuffer> surfaceBuffer)
1335 {
1336     int32_t err = sInfo_.surface->DetachBufferFromQueue(surfaceBuffer);
1337     CHECK_AND_RETURN_RET_LOG(
1338         err == 0, err, "Surface(%{public}" PRIu64 "), detach buffer(%{public}u) to queue failed, GSError=%{public}d",
1339         sInfo_.surface->GetUniqueId(), surfaceBuffer->GetSeqNum(), err);
1340     return AVCS_ERR_OK;
1341 }
1342 
FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> & surfaceMemory,uint32_t index)1343 int32_t FCodec::FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> &surfaceMemory, uint32_t index)
1344 {
1345     sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
1346     CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, AVCS_ERR_UNKNOWN, "Get surface buffer failed!");
1347     if (!surfaceMemory->isAttached) {
1348         int32_t ret = Attach(surfaceBuffer);
1349         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Surface buffer attach failed!");
1350         surfaceMemory->isAttached = true;
1351     }
1352     OHOS::BufferFlushConfig flushConfig = {{0, 0, surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight()},
1353         outAVBuffer4Surface_[index]->pts_, -1};
1354     surfaceMemory->UpdateSurfaceBufferScaleMode();
1355     if (outAVBuffer4Surface_[index]->meta_->Find(OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP) !=
1356         outAVBuffer4Surface_[index]->meta_->end()) {
1357         outAVBuffer4Surface_[index]->meta_->Get<OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP>(
1358             flushConfig.desiredPresentTimestamp);
1359         outAVBuffer4Surface_[index]->meta_->Remove(OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP);
1360     }
1361     auto res = sInfo_.surface->FlushBuffer(surfaceBuffer, -1, flushConfig);
1362     if (res == GSERROR_BUFFER_NOT_INCACHE) {
1363         AVCODEC_LOGW("Surface(%{public}" PRIu64 "), flush buffer(seq=%{public}u) failed, try to recover",
1364                      sInfo_.surface->GetUniqueId(), surfaceBuffer->GetSeqNum());
1365         int32_t ret = ClearSurfaceAndSetQueueSize(sInfo_.surface, outputBufferCnt_);
1366         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Clean surface and set queue size failed!");
1367         ret = Attach(surfaceBuffer);
1368         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Surface buffer attach failed!");
1369         surfaceMemory->isAttached = true;
1370         res = sInfo_.surface->FlushBuffer(surfaceBuffer, -1, flushConfig);
1371     }
1372     surfaceMemory->owner = Owner::OWNED_BY_SURFACE;
1373     if (res != OHOS::SurfaceError::SURFACE_ERROR_OK) {
1374         AVCODEC_LOGW("Failed to update surface memory: %{public}d", res);
1375         return AVCS_ERR_UNKNOWN;
1376     }
1377     renderSurfaceBufferMap_[index] = std::make_pair(surfaceBuffer, flushConfig);
1378     return AVCS_ERR_OK;
1379 }
1380 
RenderOutputBuffer(uint32_t index)1381 int32_t FCodec::RenderOutputBuffer(uint32_t index)
1382 {
1383     AVCODEC_SYNC_TRACE;
1384     CHECK_AND_RETURN_RET_LOG(sInfo_.surface != nullptr, AVCS_ERR_UNSUPPORT,
1385                              "Render output buffer failed, surface is nullptr!");
1386     std::unique_lock<std::mutex> oLock(outputMutex_);
1387     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_OUTPUT].size(), AVCS_ERR_INVALID_VAL,
1388                              "Failed to render output buffer: invalid index");
1389     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1390     oLock.unlock();
1391     std::lock_guard<std::mutex> sLock(surfaceMutex_);
1392     if (frameBuffer->owner_ == Owner::OWNED_BY_USER) {
1393         std::shared_ptr<FSurfaceMemory> surfaceMemory = frameBuffer->sMemory_;
1394         int32_t ret = FlushSurfaceMemory(surfaceMemory, index);
1395         if (ret != AVCS_ERR_OK) {
1396             AVCODEC_LOGW("Flush surface memory(index=%{public}u) failed: %{public}d", index, ret);
1397         } else {
1398             AVCODEC_LOGD("Flush surface memory(index=%{public}u) successful.", index);
1399         }
1400         frameBuffer->owner_ = Owner::OWNED_BY_SURFACE;
1401         renderAvailQue_->Push(index);
1402         AVCODEC_LOGD("render output buffer with index, index=%{public}u", index);
1403         return AVCS_ERR_OK;
1404     } else {
1405         AVCODEC_LOGE("Failed to render output buffer with bad index, index=%{public}u", index);
1406         return AVCS_ERR_INVALID_VAL;
1407     }
1408 }
1409 
ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface)1410 int32_t FCodec::ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface)
1411 {
1412     CHECK_AND_RETURN_RET_LOG(sInfo_.surface != nullptr, AV_ERR_OPERATE_NOT_PERMIT,
1413                              "Not support convert from AVBuffer Mode to Surface Mode");
1414     sptr<Surface> oldSurface = sInfo_.surface;
1415     uint64_t oldId = oldSurface->GetUniqueId();
1416     uint64_t newId = newSurface->GetUniqueId();
1417     AVCODEC_LOGI("Begin to switch surface %{public}" PRIu64 " -> %{public}" PRIu64 ".", oldId, newId);
1418     if (oldId == newId) {
1419         return AVCS_ERR_OK;
1420     }
1421     GSError err = RegisterListenerToSurface(newSurface);
1422     CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, err,
1423         "surface %{public}" PRIu64 ", RegisterListenerToSurface failed, GSError=%{public}d", newId, err);
1424     int32_t outputBufferCnt = 0;
1425     CHECK_AND_RETURN_RET_LOG(
1426         format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, outputBufferCnt) &&
1427         outputBufferCnt >= DEFAULT_MIN_BUFFER_CNT, AVCS_ERR_INVALID_VAL,
1428         "Invalid output buffer cnt: %{public}d", outputBufferCnt);
1429     int32_t ret = SetQueueSize(newSurface, outputBufferCnt);
1430     if (ret != AVCS_ERR_OK) {
1431         UnRegisterListenerToSurface(newSurface);
1432         return ret;
1433     }
1434     std::unique_lock<std::mutex> sLock(surfaceMutex_);
1435     ret = SwitchBetweenSurface(newSurface);
1436     if (ret != AVCS_ERR_OK) {
1437         UnRegisterListenerToSurface(newSurface);
1438         sInfo_.surface = oldSurface;
1439         CombineConsumerUsage();
1440         return ret;
1441     }
1442     sLock.unlock();
1443     AVCODEC_LOGI("Switch surface %{public}" PRIu64 " -> %{public}" PRIu64 ".", oldId, newId);
1444     return AVCS_ERR_OK;
1445 }
1446 
SetQueueSize(const sptr<Surface> & surface,uint32_t targetSize)1447 int32_t FCodec::SetQueueSize(const sptr<Surface> &surface, uint32_t targetSize)
1448 {
1449     uint64_t surfaceId = surface->GetUniqueId();
1450     int32_t err = surface->SetQueueSize(targetSize);
1451     CHECK_AND_RETURN_RET_LOG(err == 0, err,
1452                              "Surface(%{public}" PRIu64 ") set queue size %{public}u failed, GSError=%{public}d",
1453                              surfaceId, targetSize, err);
1454     AVCODEC_LOGI("Surface(%{public}" PRIu64 ") set queue size %{public}u succss.", surfaceId, targetSize);
1455     return AVCS_ERR_OK;
1456 }
1457 
SwitchBetweenSurface(const sptr<Surface> & newSurface)1458 int32_t FCodec::SwitchBetweenSurface(const sptr<Surface> &newSurface)
1459 {
1460     sptr<Surface> curSurface = sInfo_.surface;
1461     newSurface->Connect(); // cleancache will work only if the surface is connected by us
1462     newSurface->CleanCache(); // make sure new surface is empty
1463     std::vector<uint32_t> ownedBySurfaceBufferIndex;
1464     uint64_t newId = newSurface->GetUniqueId();
1465     for (uint32_t index = 0; index < buffers_[INDEX_OUTPUT].size(); index++) {
1466         if (buffers_[INDEX_OUTPUT][index]->sMemory_ == nullptr) {
1467             continue;
1468         }
1469         sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1470         if (buffers_[INDEX_OUTPUT][index]->owner_ == Owner::OWNED_BY_SURFACE) {
1471             if (renderSurfaceBufferMap_.count(index)) {
1472                 surfaceBuffer = renderSurfaceBufferMap_[index].first;
1473                 ownedBySurfaceBufferIndex.push_back(index);
1474             }
1475         } else {
1476             RequestSurfaceBufferOnce(index);
1477             surfaceBuffer = buffers_[INDEX_OUTPUT][index]->sMemory_->GetSurfaceBuffer();
1478         }
1479         CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, AVCS_ERR_UNKNOWN, "Get old surface buffer error!");
1480         int32_t err = newSurface->AttachBufferToQueue(surfaceBuffer);
1481         CHECK_AND_RETURN_RET_LOG(
1482             err == 0, err, "surface(%{public}" PRIu64 ")attach buffer(seq=%{public}u) to queue failed,"
1483             "GSError=%{public}d", newId, surfaceBuffer->GetSeqNum(), err);
1484         buffers_[INDEX_OUTPUT][index]->sMemory_->isAttached = true;
1485     }
1486     int32_t videoRotation = 0;
1487     CHECK_AND_RETURN_RET_LOG(
1488         format_.GetIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, videoRotation) && videoRotation >= 0 &&
1489         videoRotation <= static_cast<int32_t>(VideoRotation::VIDEO_ROTATION_270), AVCS_ERR_INVALID_VAL,
1490         "Invalid rotation angle %{public}d", videoRotation);
1491     sInfo_.surface->SetTransform(TranslateSurfaceRotation(static_cast<VideoRotation>(videoRotation)));
1492     int32_t scalingMode = 0;
1493     CHECK_AND_RETURN_RET_LOG(
1494         format_.GetIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, scalingMode) && scalingMode >= 0 &&
1495         scalingMode <= static_cast<int32_t>(ScalingMode::SCALING_MODE_SCALE_FIT), AVCS_ERR_INVALID_VAL,
1496         "Invalid scaling mode %{public}d", scalingMode);
1497     sInfo_.scalingMode = static_cast<ScalingMode>(scalingMode);
1498     sInfo_.surface = newSurface;
1499     CombineConsumerUsage();
1500     for (uint32_t index: ownedBySurfaceBufferIndex) {
1501         int32_t ret = RenderNewSurfaceWithOldBuffer(newSurface, index);
1502         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Old surface buffer render failed!");
1503     }
1504     int32_t ret = UnRegisterListenerToSurface(curSurface);
1505     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Unregister old surface listener failed!");
1506     curSurface->CleanCache(true); // make sure old surface is empty and go black
1507     return AVCS_ERR_OK;
1508 }
1509 
RenderNewSurfaceWithOldBuffer(const sptr<Surface> & newSurface,uint32_t index)1510 int32_t FCodec::RenderNewSurfaceWithOldBuffer(const sptr<Surface> &newSurface, uint32_t index)
1511 {
1512     std::shared_ptr<FSurfaceMemory> surfaceMemory = buffers_[INDEX_OUTPUT][index]->sMemory_;
1513     sptr<SurfaceBuffer> surfaceBuffer = renderSurfaceBufferMap_[index].first;
1514     OHOS::BufferFlushConfig flushConfig = renderSurfaceBufferMap_[index].second;
1515     newSurface->SetScalingMode(surfaceBuffer->GetSeqNum(), sInfo_.scalingMode);
1516     auto res = newSurface->FlushBuffer(surfaceBuffer, -1, flushConfig);
1517     if (res != OHOS::SurfaceError::SURFACE_ERROR_OK) {
1518         AVCODEC_LOGE("Failed to update surface memory: %{public}d", res);
1519         return AVCS_ERR_UNKNOWN;
1520     }
1521     return AVCS_ERR_OK;
1522 }
1523 
RequestBufferFromConsumer()1524 void FCodec::RequestBufferFromConsumer()
1525 {
1526     auto index = renderAvailQue_->Front();
1527     if (!RequestSurfaceBufferOnce(index)) {
1528         AVCODEC_LOGE("get buffer failed.");
1529         return;
1530     }
1531     std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
1532     std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
1533     auto queSize = renderAvailQue_->Size();
1534     uint32_t curIndex = 0;
1535     uint32_t i = 0;
1536     for (i = 0; i < queSize; i++) {
1537         curIndex = renderAvailQue_->Pop();
1538         if (surfaceMemory->GetBase() == buffers_[INDEX_OUTPUT][curIndex]->avBuffer_->memory_->GetAddr() &&
1539             surfaceMemory->GetSize() == buffers_[INDEX_OUTPUT][curIndex]->avBuffer_->memory_->GetCapacity()) {
1540             buffers_[INDEX_OUTPUT][index]->sMemory_ = buffers_[INDEX_OUTPUT][curIndex]->sMemory_;
1541             buffers_[INDEX_OUTPUT][curIndex]->sMemory_ = surfaceMemory;
1542             break;
1543         } else {
1544             renderAvailQue_->Push(curIndex);
1545         }
1546     }
1547     if (i == queSize) {
1548         curIndex = index;
1549         outputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer(surfaceMemory->GetBase(), surfaceMemory->GetSize());
1550         outputBuffer->width_ = width_;
1551         outputBuffer->height_ = height_;
1552         FindAvailIndex(curIndex);
1553     }
1554     buffers_[INDEX_OUTPUT][curIndex]->owner_ = Owner::OWNED_BY_CODEC;
1555     codecAvailQue_->Push(curIndex);
1556     if (renderSurfaceBufferMap_.count(curIndex)) {
1557         renderSurfaceBufferMap_.erase(curIndex);
1558     }
1559     AVCODEC_LOGD("Request output buffer success, index = %{public}u, queSize=%{public}zu, i=%{public}d", curIndex,
1560                  queSize, i);
1561 }
1562 
BufferReleasedByConsumer(uint64_t surfaceId)1563 GSError FCodec::BufferReleasedByConsumer(uint64_t surfaceId)
1564 {
1565     CHECK_AND_RETURN_RET_LOG(state_ == State::RUNNING || state_ == State::EOS, GSERROR_NO_PERMISSION, "In valid state");
1566     std::lock_guard<std::mutex> sLock(surfaceMutex_);
1567     CHECK_AND_RETURN_RET_LOG(renderAvailQue_->Size() > 0, GSERROR_NO_BUFFER, "No available buffer");
1568     CHECK_AND_RETURN_RET_LOG(surfaceId == sInfo_.surface->GetUniqueId(), GSERROR_INVALID_ARGUMENTS,
1569                              "Ignore callback from old surface");
1570     RequestBufferFromConsumer();
1571     return GSERROR_OK;
1572 }
1573 
UnRegisterListenerToSurface(const sptr<Surface> & surface)1574 int32_t FCodec::UnRegisterListenerToSurface(const sptr<Surface> &surface)
1575 {
1576     CHECK_AND_RETURN_RET_LOGD(surface != nullptr, AVCS_ERR_OK, "Surface is null, not need to unregister listener.");
1577     uint64_t surfaceId = surface->GetUniqueId();
1578     std::lock_guard<std::mutex> gLock(g_surfaceMapMutex);
1579     if (g_surfaceCntMap.count(surfaceId) > 0) {
1580         if (g_surfaceCntMap[surfaceId] > 1) {
1581             g_surfaceCntMap[surfaceId] -= 1;
1582             AVCODEC_LOGI("Surface(%{public}" PRIu64 ") not need to unregister listener.", surfaceId);
1583             return AVCS_ERR_OK;
1584         }
1585         CHECK_AND_RETURN_RET_LOGD(g_surfaceCntMap[surfaceId] == 1, AVCS_ERR_OK,
1586                                   "Surface(%{public}" PRIu64 ") not need to unregister listener.", surfaceId);
1587         GSError err = surface->UnRegisterReleaseListener();
1588         CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, err,
1589                                  "Surface(%{public}" PRIu64 ") UnRegisterReleaseListener failed, GSError=%{public}d",
1590                                  surfaceId, err);
1591         g_surfaceCntMap.erase(surfaceId);
1592         AVCODEC_LOGI("Surface(%{public}" PRIu64 ") UnRegisterReleaseListener success.", surfaceId);
1593     }
1594     return AVCS_ERR_OK;
1595 }
1596 
RegisterListenerToSurface(const sptr<Surface> & surface)1597 GSError FCodec::RegisterListenerToSurface(const sptr<Surface> &surface)
1598 {
1599     uint64_t surfaceId = surface->GetUniqueId();
1600     wptr<FCodec> wp = this;
1601     GSError err = surface->RegisterReleaseListener([wp, surfaceId](sptr<SurfaceBuffer> &) {
1602         sptr<FCodec> codec = wp.promote();
1603         if (!codec) {
1604             AVCODEC_LOGD("decoder is gone");
1605             return GSERROR_OK;
1606         }
1607         return codec->BufferReleasedByConsumer(surfaceId);
1608     });
1609     if (err == GSERROR_OK) {
1610         StartRequestSurfaceBufferThread();
1611     }
1612     std::lock_guard<std::mutex> gLock(g_surfaceMapMutex);
1613     if (g_surfaceCntMap.count(surfaceId) == 0) {
1614         g_surfaceCntMap.emplace(surfaceId, 1);
1615     } else {
1616         g_surfaceCntMap[surfaceId] += 1;
1617     }
1618     return err;
1619 }
1620 
CombineConsumerUsage()1621 void FCodec::CombineConsumerUsage()
1622 {
1623     uint64_t defaultUsage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
1624     uint64_t consumerUsage = sInfo_.surface->GetDefaultUsage();
1625     uint64_t cfgedUsage = sInfo_.requestConfig.usage;
1626     uint64_t finalUsage = defaultUsage | consumerUsage | cfgedUsage;
1627     sInfo_.requestConfig.usage = finalUsage;
1628     AVCODEC_LOGI("Usage: default(0x%{public}" PRIu64 ") | consumer(0x%{public}" PRIu64 ") | cfged(0x%{public}" PRIu64
1629                  ") -> final(0x%{public}" PRIu64 ").",
1630                  defaultUsage, consumerUsage, cfgedUsage, finalUsage);
1631 }
1632 
SetOutputSurface(sptr<Surface> surface)1633 int32_t FCodec::SetOutputSurface(sptr<Surface> surface)
1634 {
1635     AVCODEC_SYNC_TRACE;
1636     CHECK_AND_RETURN_RET_LOG(state_ != State::UNINITIALIZED, AV_ERR_INVALID_VAL,
1637                              "set output surface fail: not initialized or configured");
1638     CHECK_AND_RETURN_RET_LOG((state_ == State::CONFIGURED || state_ == State::FLUSHED ||
1639         state_ == State::RUNNING || state_ == State::EOS), AVCS_ERR_INVALID_STATE,
1640         "set output surface fail: state %{public}d not support set output surface",
1641         static_cast<int32_t>(state_.load()));
1642     if (surface == nullptr || surface->IsConsumer()) {
1643         AVCODEC_LOGE("Set surface fail");
1644         return AVCS_ERR_INVALID_VAL;
1645     }
1646     if (state_ == State::FLUSHED || state_ == State::RUNNING || state_ == State::EOS) {
1647         return ReplaceOutputSurfaceWhenRunning(surface);
1648     }
1649     int32_t ret = UnRegisterListenerToSurface(sInfo_.surface);
1650     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Unregister listener to surface failed, ret=%{public}d", ret);
1651     uint64_t surfaceId = surface->GetUniqueId();
1652     sInfo_.surface = surface;
1653     CombineConsumerUsage();
1654     GSError err = RegisterListenerToSurface(sInfo_.surface);
1655     CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, err,
1656                              "surface(%{public}" PRIu64 ") register listener to surface failed, GSError=%{public}d",
1657                              sInfo_.surface->GetUniqueId(), err);
1658     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_SCALE_TYPE)) {
1659         std::lock_guard<std::mutex> lock(formatMutex_);
1660         format_.PutIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE,
1661                             static_cast<int32_t>(ScalingMode::SCALING_MODE_SCALE_TO_WINDOW));
1662     }
1663     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE)) {
1664         std::lock_guard<std::mutex> lock(formatMutex_);
1665         format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE,
1666                             static_cast<int32_t>(VideoRotation::VIDEO_ROTATION_0));
1667     }
1668     AVCODEC_LOGI("Set surface(%{public}" PRIu64 ") success.", surfaceId);
1669     return AVCS_ERR_OK;
1670 }
1671 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)1672 int32_t FCodec::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
1673 {
1674     AVCODEC_SYNC_TRACE;
1675     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Set callback failed: callback is NULL");
1676     callback_ = callback;
1677     return AVCS_ERR_OK;
1678 }
1679 
GetMpeg2CapProf(std::vector<CapabilityData> & capaArray)1680 void FCodec::GetMpeg2CapProf(std::vector<CapabilityData> &capaArray)
1681 {
1682     if (!capaArray.empty()) {
1683         CapabilityData& capsData = capaArray.back();
1684         capsData.profiles = {static_cast<int32_t>(MPEG2_PROFILE_422), static_cast<int32_t>(MPEG2_PROFILE_HIGH),
1685                             static_cast<int32_t>(MPEG2_PROFILE_MAIN), static_cast<int32_t>(MPEG2_PROFILE_SNR),
1686                             static_cast<int32_t>(MPEG2_PROFILE_SIMPLE), static_cast<int32_t>(MPEG2_PROFILE_SPATIAL)};
1687         std::vector<int32_t> levels_sp;
1688         std::vector<int32_t> levels_mp;
1689         std::vector<int32_t> levels_snr;
1690         std::vector<int32_t> levels_422p;
1691         for (int32_t j = 0; j <= static_cast<int32_t>(MPEG2Level::MPEG2_LEVEL_ML); ++j) {
1692             levels_sp.emplace_back(j);
1693         }
1694         for (int32_t j = 0; j <= static_cast<int32_t>(MPEG2Level::MPEG2_LEVEL_HL); ++j) {
1695             levels_mp.emplace_back(j);
1696         }
1697         for (int32_t j = 0; j <= static_cast<int32_t>(MPEG2Level::MPEG2_LEVEL_H14); ++j) {
1698             levels_snr.emplace_back(j);
1699         }
1700         for (int32_t j = static_cast<int32_t>(MPEG2Level::MPEG2_LEVEL_ML);
1701                 j <= static_cast<int32_t>(MPEG2Level::MPEG2_LEVEL_HL); ++j) {
1702             levels_422p.emplace_back(j);
1703         }
1704         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_SIMPLE), levels_sp));
1705         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_MAIN), levels_mp));
1706         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_SNR), levels_snr));
1707         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_SPATIAL), levels_mp));
1708         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_HIGH), levels_mp));
1709         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(MPEG2_PROFILE_422), levels_422p));
1710     }
1711 }
1712 
SetMpeg4Profiles(CapabilityData & capsData)1713 void FCodec::SetMpeg4Profiles(CapabilityData& capsData)
1714 {
1715     capsData.profiles = {
1716         static_cast<int32_t>(MPEG4_PROFILE_SIMPLE),
1717         static_cast<int32_t>(MPEG4_PROFILE_SIMPLE_SCALABLE),
1718         static_cast<int32_t>(MPEG4_PROFILE_CORE),
1719         static_cast<int32_t>(MPEG4_PROFILE_MAIN),
1720         static_cast<int32_t>(MPEG4_PROFILE_NBIT),
1721         static_cast<int32_t>(MPEG4_PROFILE_HYBRID),
1722         static_cast<int32_t>(MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE),
1723         static_cast<int32_t>(MPEG4_PROFILE_SCALABLE_TEXTURE),
1724         static_cast<int32_t>(MPEG4_PROFILE_SIMPLE_FA),
1725         static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_REAL_TIME_SIMPLE),
1726         static_cast<int32_t>(MPEG4_PROFILE_CORE_SCALABLE),
1727         static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY),
1728         static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_CORE),
1729         static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE),
1730         static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_SIMPLE),
1731     };
1732 }
1733 
SetMpeg4LevelsProfileGroup1(CapabilityData & capsData)1734 void FCodec::SetMpeg4LevelsProfileGroup1(CapabilityData& capsData)
1735 {
1736     capsData.profileLevelsMap = {
1737         {static_cast<int32_t>(MPEG4_PROFILE_SIMPLE), {
1738             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_0), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_0B),
1739             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2),
1740             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_4A),
1741             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_5), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_6)
1742         }},
1743         {static_cast<int32_t>(MPEG4_PROFILE_SIMPLE_SCALABLE), {
1744             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_0), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1),
1745             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1746         }},
1747         {static_cast<int32_t>(MPEG4_PROFILE_CORE), {
1748             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1749         }},
1750         {static_cast<int32_t>(MPEG4_PROFILE_MAIN), {
1751             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3),
1752             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_4)
1753         }},
1754         {static_cast<int32_t>(MPEG4_PROFILE_NBIT), {
1755             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1756         }},
1757         {static_cast<int32_t>(MPEG4_PROFILE_HYBRID), {
1758             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1759         }},
1760         {static_cast<int32_t>(MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE), {
1761             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1762         }},
1763         {static_cast<int32_t>(MPEG4_PROFILE_SCALABLE_TEXTURE), {
1764             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1)
1765         }}
1766     };
1767 }
1768 
SetMpeg4LevelsProfileGroup2(CapabilityData & capsData)1769 void FCodec::SetMpeg4LevelsProfileGroup2(CapabilityData& capsData)
1770 {
1771     capsData.profileLevelsMap.insert({
1772         {static_cast<int32_t>(MPEG4_PROFILE_SIMPLE_FA), {
1773             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1774         }},
1775         {static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_REAL_TIME_SIMPLE), {
1776             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2),
1777             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_4)
1778         }},
1779         {static_cast<int32_t>(MPEG4_PROFILE_CORE_SCALABLE), {
1780             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2),
1781             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3)
1782         }},
1783         {static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY), {
1784             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2),
1785             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_4)
1786         }},
1787         {static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_CORE), {
1788             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2)
1789         }},
1790         {static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE), {
1791             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2),
1792             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3)
1793         }},
1794         {static_cast<int32_t>(MPEG4_PROFILE_ADVANCED_SIMPLE), {
1795             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_0), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_1),
1796             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_2), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3),
1797             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_3B), static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_4),
1798             static_cast<int32_t>(MPEG4Level::MPEG4_LEVEL_5)
1799         }}
1800     });
1801 }
1802 
GetMpeg4esCapProf(std::vector<CapabilityData> & capaArray)1803 void FCodec::GetMpeg4esCapProf(std::vector<CapabilityData>& capaArray)
1804 {
1805     if (!capaArray.empty()) {
1806         CapabilityData& capsData = capaArray.back();
1807         SetMpeg4Profiles(capsData);
1808         SetMpeg4LevelsProfileGroup1(capsData);
1809         SetMpeg4LevelsProfileGroup2(capsData);
1810     }
1811 }
1812 
GetH263CapProf(std::vector<CapabilityData> & capaArray)1813 void FCodec::GetH263CapProf(std::vector<CapabilityData> &capaArray)
1814 {
1815     if (!capaArray.empty()) {
1816         CapabilityData& capsData = capaArray.back();
1817         capsData.profiles = {static_cast<int32_t>(H263_PROFILE_BASELINE),
1818                              static_cast<int32_t>(H263_PROFILE_VERSION_1_BACKWARD_COMPATIBILITY)};
1819         std::vector<int32_t> levels;
1820         for (int32_t j = 0; j <= static_cast<int32_t>(H263Level::H263_LEVEL_70); ++j) {
1821             levels.emplace_back(j);
1822         }
1823         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(H263_PROFILE_BASELINE), levels));
1824         capsData.profileLevelsMap.insert(
1825             std::make_pair(static_cast<int32_t>(H263_PROFILE_VERSION_1_BACKWARD_COMPATIBILITY), levels));
1826     }
1827     return;
1828 }
1829 
GetAvcCapProf(std::vector<CapabilityData> & capaArray)1830 void FCodec::GetAvcCapProf(std::vector<CapabilityData> &capaArray)
1831 {
1832     if (!capaArray.empty()) {
1833         CapabilityData& capsData = capaArray.back();
1834         capsData.profiles = {static_cast<int32_t>(AVC_PROFILE_BASELINE), static_cast<int32_t>(AVC_PROFILE_MAIN),
1835                                     static_cast<int32_t>(AVC_PROFILE_HIGH)};
1836         std::vector<int32_t> levels;
1837         for (int32_t j = 0; j <= static_cast<int32_t>(AVCLevel::AVC_LEVEL_51); ++j) {
1838             levels.emplace_back(j);
1839         }
1840         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_MAIN), levels));
1841         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_HIGH), levels));
1842         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_BASELINE), levels));
1843     }
1844 }
1845 
GetCodecCapability(std::vector<CapabilityData> & capaArray)1846 int32_t FCodec::GetCodecCapability(std::vector<CapabilityData> &capaArray)
1847 {
1848     for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
1849         CapabilityData capsData;
1850         capsData.codecName = static_cast<std::string>(SUPPORT_VCODEC[i].codecName);
1851         capsData.mimeType = static_cast<std::string>(SUPPORT_VCODEC[i].mimeType);
1852         capsData.codecType = SUPPORT_VCODEC[i].isEncoder ? AVCODEC_TYPE_VIDEO_ENCODER : AVCODEC_TYPE_VIDEO_DECODER;
1853         capsData.isVendor = false;
1854         capsData.maxInstance = VIDEO_INSTANCE_SIZE;
1855         capsData.alignment.width = VIDEO_ALIGNMENT_SIZE;
1856         capsData.alignment.height = VIDEO_ALIGNMENT_SIZE;
1857         capsData.width.minVal = capsData.mimeType == "video/h263" ? VIDEO_MIN_WIDTH_H263_SIZE : VIDEO_MIN_SIZE;
1858         capsData.height.minVal = capsData.mimeType == "video/h263" ? VIDEO_MIN_HEIGHT_H263_SIZE : VIDEO_MIN_SIZE;
1859         capsData.width.maxVal = capsData.mimeType == "video/h263" ? VIDEO_MAX_WIDTH_H263_SIZE : VIDEO_MAX_WIDTH_SIZE;
1860         capsData.height.maxVal = capsData.mimeType == "video/h263" ? VIDEO_MAX_HEIGHT_H263_SIZE : VIDEO_MAX_HEIGHT_SIZE;
1861         capsData.frameRate.minVal = 0;
1862         capsData.frameRate.maxVal = VIDEO_FRAMERATE_DEFAULT_SIZE;
1863         capsData.bitrate.minVal = 1;
1864         capsData.bitrate.maxVal = VIDEO_BITRATE_MAX_SIZE;
1865         capsData.blockPerFrame.minVal = 1;
1866         capsData.blockPerFrame.maxVal = VIDEO_BLOCKPERFRAME_SIZE;
1867         capsData.blockPerSecond.minVal = 1;
1868         capsData.blockPerSecond.maxVal = VIDEO_BLOCKPERSEC_SIZE;
1869         capsData.blockSize.width = VIDEO_ALIGN_SIZE;
1870         capsData.blockSize.height = VIDEO_ALIGN_SIZE;
1871         if (SUPPORT_VCODEC[i].isEncoder) {
1872             capsData.complexity.minVal = 0;
1873             capsData.complexity.maxVal = 0;
1874             capsData.encodeQuality.minVal = 0;
1875             capsData.encodeQuality.maxVal = 0;
1876         }
1877         capsData.pixFormat = {
1878             static_cast<int32_t>(VideoPixelFormat::YUVI420), static_cast<int32_t>(VideoPixelFormat::NV12),
1879             static_cast<int32_t>(VideoPixelFormat::NV21), static_cast<int32_t>(VideoPixelFormat::RGBA)};
1880         if (capsData.mimeType == "video/mpeg2") {
1881             capaArray.emplace_back(capsData);
1882             GetMpeg2CapProf(capaArray);
1883         } else if (capsData.mimeType == "video/mp4v-es") {
1884             capaArray.emplace_back(capsData);
1885             GetMpeg4esCapProf(capaArray);
1886         } else if (capsData.mimeType == "video/h263") {
1887             capaArray.emplace_back(capsData);
1888             GetH263CapProf(capaArray);
1889         } else {
1890             capsData.frameRate.maxVal = VIDEO_FRAMERATE_MAX_SIZE;
1891             capaArray.emplace_back(capsData);
1892             GetAvcCapProf(capaArray);
1893         }
1894     }
1895     return AVCS_ERR_OK;
1896 }
1897 } // namespace Codec
1898 } // namespace MediaAVCodec
1899 } // namespace OHOS
1900