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 <iostream>
17 #include <set>
18 #include <thread>
19 #include <malloc.h>
20 #include "syspara/parameters.h"
21 #include "securec.h"
22 #include "avcodec_trace.h"
23 #include "avcodec_log.h"
24 #include "utils.h"
25 #include "avcodec_codec_name.h"
26 #include "fcodec.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 DEFAULT_VIDEO_WIDTH = 1920;
46 constexpr int32_t DEFAULT_VIDEO_HEIGHT = 1080;
47 constexpr uint32_t DEFAULT_TRY_DECODE_TIME = 1;
48 constexpr uint32_t DEFAULT_TRY_REQ_TIME = 10;
49 constexpr uint32_t DEFAULT_DECODE_WAIT_TIME = 200;
50 constexpr int32_t VIDEO_INSTANCE_SIZE = 64;
51 constexpr int32_t VIDEO_BITRATE_MAX_SIZE = 300000000;
52 constexpr int32_t VIDEO_FRAMERATE_MAX_SIZE = 120;
53 constexpr int32_t VIDEO_BLOCKPERFRAME_SIZE = 36864;
54 constexpr int32_t VIDEO_BLOCKPERSEC_SIZE = 983040;
55 constexpr int32_t DEFAULT_THREAD_COUNT = 2;
56 #ifdef BUILD_ENG_VERSION
57 constexpr uint32_t PATH_MAX_LEN = 128;
58 constexpr char DUMP_PATH[] = "/data/misc/fcodecdump";
59 #endif // BUILD_ENG_VERSION
60 constexpr struct {
61     const std::string_view codecName;
62     const std::string_view mimeType;
63     const char *ffmpegCodec;
64     const bool isEncoder;
65 } SUPPORT_VCODEC[] = {
66     {AVCodecCodecName::VIDEO_DECODER_AVC_NAME, CodecMimeType::VIDEO_AVC, "h264", false},
67 };
68 constexpr uint32_t SUPPORT_VCODEC_NUM = sizeof(SUPPORT_VCODEC) / sizeof(SUPPORT_VCODEC[0]);
69 } // namespace
70 using namespace OHOS::Media;
FCodec(const std::string &name)71 FCodec::FCodec(const std::string &name) : codecName_(name), state_(State::UNINITIALIZED)
72 {
73     AVCODEC_SYNC_TRACE;
74     AVCODEC_LOGD("Fcodec entered, state: Uninitialized");
75 }
76 
~FCodec()77 FCodec::~FCodec()
78 {
79     ReleaseResource();
80     callback_ = nullptr;
81 #ifdef BUILD_ENG_VERSION
82     if (dumpInFile_ != nullptr) {
83         dumpInFile_->close();
84     }
85     if (dumpOutFile_ != nullptr) {
86         dumpOutFile_->close();
87     }
88 #endif // BUILD_ENG_VERSION
89     mallopt(M_FLUSH_THREAD_CACHE, 0);
90 }
91 
92 #ifdef BUILD_ENG_VERSION
OpenDumpFile()93 void FCodec::OpenDumpFile()
94 {
95     std::string dumpModeStr = OHOS::system::GetParameter("fcodec.dump", "0");
96     AVCODEC_LOGI("dumpModeStr %{public}s", dumpModeStr.c_str());
97     CHECK_AND_RETURN_LOG(dumpModeStr.length() == 2, "dumpModeStr length should equal 2"); // 2
98     char fileName[PATH_MAX_LEN] = {0};
99     int ret;
100     if (dumpModeStr[0] == '1') {
101         ret = sprintf_s(fileName, sizeof(fileName), "%s/input_%p.h264", DUMP_PATH, this);
102         CHECK_AND_RETURN_LOG(ret > 0, "Fail to sprintf input fileName");
103         dumpInFile_ = std::make_shared<std::ofstream>();
104         dumpInFile_->open(fileName, std::ios::out | std::ios::binary);
105         if (!dumpInFile_->is_open()) {
106             AVCODEC_LOGW("fail open file %{public}s", fileName);
107             dumpInFile_ = nullptr;
108         }
109     }
110 
111     if (dumpModeStr[1] == '1') {
112         ret = sprintf_s(fileName, sizeof(fileName), "%s/output_%p.yuv", DUMP_PATH, this);
113         CHECK_AND_RETURN_LOG(ret > 0, "Fail to sprintf output fileName");
114         dumpOutFile_ = std::make_shared<std::ofstream>();
115         dumpOutFile_->open(fileName, std::ios::out | std::ios::binary);
116         if (!dumpOutFile_->is_open()) {
117             AVCODEC_LOGW("fail open file %{public}s", fileName);
118             dumpOutFile_ = nullptr;
119         }
120     }
121 }
122 #endif // BUILD_ENG_VERSION
123 
Initialize()124 int32_t FCodec::Initialize()
125 {
126     AVCODEC_SYNC_TRACE;
127     CHECK_AND_RETURN_RET_LOG(!codecName_.empty(), AVCS_ERR_INVALID_VAL, "Init codec failed:  empty name");
128     std::string fcodecName;
129     std::string_view mime;
130     for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
131         if (SUPPORT_VCODEC[i].codecName == codecName_) {
132             fcodecName = SUPPORT_VCODEC[i].ffmpegCodec;
133             mime = SUPPORT_VCODEC[i].mimeType;
134             break;
135         }
136     }
137     CHECK_AND_RETURN_RET_LOG(!fcodecName.empty(), AVCS_ERR_INVALID_VAL,
138                              "Init codec failed: not support name: %{public}s", codecName_.c_str());
139     format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, mime);
140     format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, codecName_);
141     avCodec_ = std::shared_ptr<AVCodec>(const_cast<AVCodec *>(avcodec_find_decoder_by_name(fcodecName.c_str())),
142                                         [](void *ptr) {});
143     CHECK_AND_RETURN_RET_LOG(avCodec_ != nullptr, AVCS_ERR_INVALID_VAL,
144                              "Init codec failed:  cannot find codec with name %{public}s", codecName_.c_str());
145     sendTask_ = std::make_shared<TaskThread>("SendFrame");
146     sendTask_->RegisterHandler([this] { SendFrame(); });
147     receiveTask_ = std::make_shared<TaskThread>("ReceiveFrame");
148     receiveTask_->RegisterHandler([this] { ReceiveFrame(); });
149 #ifdef BUILD_ENG_VERSION
150     OpenDumpFile();
151 #endif // BUILD_ENG_VERSION
152     state_ = State::INITIALIZED;
153     AVCODEC_LOGI("Init codec successful,  state: Uninitialized -> Initialized");
154     return AVCS_ERR_OK;
155 }
156 
ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal, int32_t maxVal)157 void FCodec::ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal,
158                                  int32_t maxVal)
159 {
160     int32_t val32 = 0;
161     if (format.GetIntValue(formatKey, val32) && val32 >= minVal && val32 <= maxVal) {
162         format_.PutIntValue(formatKey, val32);
163     } else {
164         AVCODEC_LOGW("Set parameter failed: %{public}s, which minimum threshold=%{public}d, "
165                      "maximum threshold=%{public}d",
166                      std::string(formatKey).c_str(), minVal, maxVal);
167     }
168 }
169 
ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType)170 void FCodec::ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType)
171 {
172     CHECK_AND_RETURN_LOG(formatType == FORMAT_TYPE_INT32, "Set parameter failed: type should be int32");
173 
174     int32_t val = 0;
175     CHECK_AND_RETURN_LOG(format.GetIntValue(formatKey, val), "Set parameter failed: get value fail");
176 
177     if (formatKey == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
178         VideoPixelFormat vpf = static_cast<VideoPixelFormat>(val);
179         CHECK_AND_RETURN_LOG(vpf == VideoPixelFormat::RGBA || vpf == VideoPixelFormat::YUVI420 ||
180                                  vpf == VideoPixelFormat::NV12 || vpf == VideoPixelFormat::NV21,
181                              "Set parameter failed: pixel format value %{public}d invalid", val);
182         outputPixelFmt_ = vpf;
183         format_.PutIntValue(formatKey, val);
184     } else if (formatKey == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE) {
185         VideoRotation sr = static_cast<VideoRotation>(val);
186         CHECK_AND_RETURN_LOG(sr == VideoRotation::VIDEO_ROTATION_0 || sr == VideoRotation::VIDEO_ROTATION_90 ||
187                                  sr == VideoRotation::VIDEO_ROTATION_180 || sr == VideoRotation::VIDEO_ROTATION_270,
188                              "Set parameter failed: rotation angle value %{public}d invalid", val);
189         format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val);
190     } else if (formatKey == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
191         ScalingMode scaleMode = static_cast<ScalingMode>(val);
192         CHECK_AND_RETURN_LOG(scaleMode == ScalingMode::SCALING_MODE_SCALE_TO_WINDOW ||
193                                  scaleMode == ScalingMode::SCALING_MODE_SCALE_CROP,
194                              "Set parameter failed: scale type value %{public}d invalid", val);
195         format_.PutIntValue(formatKey, val);
196     } else {
197         AVCODEC_LOGW("Set parameter failed: %{public}s, please check your parameter key",
198                      std::string(formatKey).c_str());
199         return;
200     }
201     AVCODEC_LOGI("Set parameter  %{public}s success, val %{public}d", std::string(formatKey).c_str(), val);
202 }
203 
ConfigureContext(const Format &format)204 int32_t FCodec::ConfigureContext(const Format &format)
205 {
206     avCodecContext_ = std::shared_ptr<AVCodecContext>(avcodec_alloc_context3(avCodec_.get()), [](AVCodecContext *p) {
207         if (p != nullptr) {
208             if (p->extradata) {
209                 av_free(p->extradata);
210                 p->extradata = nullptr;
211             }
212             avcodec_free_context(&p);
213         }
214     });
215     CHECK_AND_RETURN_RET_LOG(avCodecContext_ != nullptr, AVCS_ERR_INVALID_OPERATION,
216                              "Configure codec failed: Allocate context error");
217     avCodecContext_->codec_type = AVMEDIA_TYPE_VIDEO;
218     format.GetIntValue(MediaDescriptionKey::MD_KEY_WIDTH, width_);
219     format.GetIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, height_);
220     format_.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE,
221                         outputPixelFmt_ == VideoPixelFormat::RGBA ? width_ * VIDEO_PIX_DEPTH_RGBA : width_);
222     format_.PutIntValue(OHOS::Media::Tag::VIDEO_SLICE_HEIGHT, height_);
223     format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_WIDTH, width_);
224     format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_HEIGHT, height_);
225 
226     avCodecContext_->width = width_;
227     avCodecContext_->height = height_;
228     avCodecContext_->thread_count = DEFAULT_THREAD_COUNT;
229     return AVCS_ERR_OK;
230 }
231 
Configure(const Format &format)232 int32_t FCodec::Configure(const Format &format)
233 {
234     AVCODEC_SYNC_TRACE;
235     if (state_ == State::UNINITIALIZED) {
236         int32_t ret = Initialize();
237         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Init codec failed");
238     }
239     CHECK_AND_RETURN_RET_LOG((state_ == State::INITIALIZED), AVCS_ERR_INVALID_STATE,
240                              "Configure codec failed:  not in Initialized state");
241     format_.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, DEFAULT_VIDEO_WIDTH);
242     format_.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, DEFAULT_VIDEO_HEIGHT);
243     format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, DEFAULT_OUT_BUFFER_CNT);
244     format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, DEFAULT_IN_BUFFER_CNT);
245     for (auto &it : format.GetFormatMap()) {
246         if (it.first == MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT) {
247             isOutBufSetted_ = true;
248             ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
249         } else if (it.first == MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT) {
250             ConfigureDefaultVal(format, it.first, DEFAULT_MIN_BUFFER_CNT);
251         } else if (it.first == MediaDescriptionKey::MD_KEY_WIDTH) {
252             ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_WIDTH_SIZE);
253         } else if (it.first == MediaDescriptionKey::MD_KEY_HEIGHT) {
254             ConfigureDefaultVal(format, it.first, VIDEO_MIN_SIZE, VIDEO_MAX_HEIGHT_SIZE);
255         } else if (it.first == MediaDescriptionKey::MD_KEY_BITRATE) {
256             int64_t val64 = 0;
257             format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64);
258             format_.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, val64);
259         } else if (it.first == MediaDescriptionKey::MD_KEY_FRAME_RATE) {
260             double val = 0;
261             format.GetDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val);
262             format_.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, val);
263         } else if (it.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT ||
264                    it.first == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE ||
265                    it.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
266             ConfigureSurface(format, it.first, it.second.type);
267         } else {
268             AVCODEC_LOGW("Set parameter failed: size:%{public}s, unsupport key", it.first.data());
269         }
270     }
271     AVCODEC_LOGI("current pixel format %{public}d", static_cast<int32_t>(outputPixelFmt_));
272     int32_t ret = ConfigureContext(format);
273 
274     state_ = State::CONFIGURED;
275     AVCODEC_LOGI("Configured codec successful: state: Initialized -> Configured");
276     return ret;
277 }
278 
IsActive() const279 bool FCodec::IsActive() const
280 {
281     return state_ == State::RUNNING || state_ == State::FLUSHED || state_ == State::EOS;
282 }
283 
ResetContext(bool isFlush)284 void FCodec::ResetContext(bool isFlush)
285 {
286     if (avCodecContext_ == nullptr) {
287         return;
288     }
289     if (avCodecContext_->extradata) {
290         av_free(avCodecContext_->extradata);
291         avCodecContext_->extradata = nullptr;
292     }
293     avCodecContext_->coded_width = 0;
294     avCodecContext_->coded_height = 0;
295     avCodecContext_->extradata_size = 0;
296     if (!isFlush) {
297         avCodecContext_->width = 0;
298         avCodecContext_->height = 0;
299         avCodecContext_->get_buffer2 = nullptr;
300     }
301 }
302 
Start()303 int32_t FCodec::Start()
304 {
305     AVCODEC_SYNC_TRACE;
306     CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Start codec failed: callback is null");
307     CHECK_AND_RETURN_RET_LOG((state_ == State::CONFIGURED || state_ == State::FLUSHED), AVCS_ERR_INVALID_STATE,
308                              "Start codec failed: not in Configured or Flushed state");
309     if (state_ != State::FLUSHED) {
310         CHECK_AND_RETURN_RET_LOG(avcodec_open2(avCodecContext_.get(), avCodec_.get(), nullptr) == 0, AVCS_ERR_UNKNOWN,
311                                  "Start codec failed: cannot open avcodec");
312     }
313     if (!isBufferAllocated_) {
314         cachedFrame_ = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame *p) { av_frame_free(&p); });
315         avPacket_ = std::shared_ptr<AVPacket>(av_packet_alloc(), [](AVPacket *p) { av_packet_free(&p); });
316         CHECK_AND_RETURN_RET_LOG((cachedFrame_ != nullptr && avPacket_ != nullptr), AVCS_ERR_UNKNOWN,
317                                  "Start codec failed: cannot allocate frame or packet");
318         for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
319             scaleData_[i] = nullptr;
320             scaleLineSize_[i] = 0;
321         }
322         isConverted_ = false;
323         int32_t ret = AllocateBuffers();
324         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Start codec failed: cannot allocate buffers");
325         isBufferAllocated_ = true;
326     }
327     state_ = State::RUNNING;
328     InitBuffers();
329     isSendEos_ = false;
330     sendTask_->Start();
331     receiveTask_->Start();
332     AVCODEC_LOGI("Start codec successful, state: Running");
333     return AVCS_ERR_OK;
334 }
335 
InitBuffers()336 void FCodec::InitBuffers()
337 {
338     inputAvailQue_->SetActive(true);
339     codecAvailQue_->SetActive(true);
340     if (sInfo_.surface != nullptr) {
341         renderAvailQue_->SetActive(true);
342     }
343     if (buffers_[INDEX_INPUT].size() > 0) {
344         for (uint32_t i = 0; i < buffers_[INDEX_INPUT].size(); i++) {
345             buffers_[INDEX_INPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_USER;
346             callback_->OnInputBufferAvailable(i, buffers_[INDEX_INPUT][i]->avBuffer_);
347             AVCODEC_LOGI("OnInputBufferAvailable frame index = %{public}d, owner = %{public}d", i,
348                          buffers_[INDEX_INPUT][i]->owner_.load());
349         }
350     }
351     if (buffers_[INDEX_OUTPUT].size() <= 0) {
352         return;
353     }
354     if (sInfo_.surface == nullptr) {
355         for (uint32_t i = 0; i < buffers_[INDEX_OUTPUT].size(); i++) {
356             buffers_[INDEX_OUTPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
357             codecAvailQue_->Push(i);
358         }
359     } else {
360         for (uint32_t i = 0; i < buffers_[INDEX_OUTPUT].size(); i++) {
361             std::shared_ptr<FSurfaceMemory> surfaceMemory = buffers_[INDEX_OUTPUT][i]->sMemory_;
362             if (surfaceMemory->GetSurfaceBuffer() == nullptr) {
363                 buffers_[INDEX_OUTPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_SURFACE;
364                 renderAvailQue_->Push(i);
365             } else {
366                 buffers_[INDEX_OUTPUT][i]->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
367                 codecAvailQue_->Push(i);
368             }
369         }
370     }
371 }
372 
ResetData()373 void FCodec::ResetData()
374 {
375     if (scaleData_[0] != nullptr) {
376         if (isConverted_) {
377             av_free(scaleData_[0]);
378             isConverted_ = false;
379             scale_.reset();
380         }
381         for (int32_t i = 0; i < AV_NUM_DATA_POINTERS; i++) {
382             scaleData_[i] = nullptr;
383             scaleLineSize_[i] = 0;
384         }
385     }
386 }
387 
ResetBuffers()388 void FCodec::ResetBuffers()
389 {
390     inputAvailQue_->Clear();
391     std::unique_lock<std::mutex> iLock(inputMutex_);
392     synIndex_ = std::nullopt;
393     iLock.unlock();
394     codecAvailQue_->Clear();
395     if (sInfo_.surface != nullptr) {
396         renderAvailQue_->Clear();
397         renderSurfaceBufferMap_.clear();
398     }
399     ResetData();
400     av_frame_unref(cachedFrame_.get());
401     av_packet_unref(avPacket_.get());
402 }
403 
StopThread()404 void FCodec::StopThread()
405 {
406     if (sendTask_ != nullptr && inputAvailQue_ != nullptr) {
407         std::unique_lock<std::mutex> sLock(sendMutex_);
408         sendCv_.notify_one();
409         sLock.unlock();
410         inputAvailQue_->SetActive(false, false);
411         sendTask_->Stop();
412     }
413     if (receiveTask_ != nullptr && codecAvailQue_ != nullptr) {
414         std::unique_lock<std::mutex> rLock(recvMutex_);
415         recvCv_.notify_one();
416         rLock.unlock();
417         codecAvailQue_->SetActive(false, false);
418         receiveTask_->Stop();
419     }
420     if (sInfo_.surface != nullptr && renderAvailQue_ != nullptr) {
421         renderAvailQue_->SetActive(false, false);
422     }
423 }
424 
Stop()425 int32_t FCodec::Stop()
426 {
427     AVCODEC_SYNC_TRACE;
428     CHECK_AND_RETURN_RET_LOG((IsActive()), AVCS_ERR_INVALID_STATE, "Stop codec failed: not in executing state");
429     state_ = State::STOPPING;
430     AVCODEC_LOGI("step into STOPPING status");
431     std::unique_lock<std::mutex> sLock(sendMutex_);
432     sendCv_.notify_one();
433     sLock.unlock();
434     inputAvailQue_->SetActive(false, false);
435     sendTask_->Stop();
436 
437     if (sInfo_.surface != nullptr) {
438         renderAvailQue_->SetActive(false, false);
439     }
440     std::unique_lock<std::mutex> rLock(recvMutex_);
441     recvCv_.notify_one();
442     rLock.unlock();
443     codecAvailQue_->SetActive(false, false);
444     receiveTask_->Stop();
445     avcodec_close(avCodecContext_.get());
446     ResetContext(true);
447     ResetBuffers();
448     state_ = State::CONFIGURED;
449     AVCODEC_LOGI("Stop codec successful, state: Configured");
450     return AVCS_ERR_OK;
451 }
452 
Flush()453 int32_t FCodec::Flush()
454 {
455     AVCODEC_SYNC_TRACE;
456     CHECK_AND_RETURN_RET_LOG((state_ == State::RUNNING || state_ == State::EOS), AVCS_ERR_INVALID_STATE,
457                              "Flush codec failed: not in running or Eos state");
458     state_ = State::FLUSHING;
459     AVCODEC_LOGI("step into FLUSHING status");
460     std::unique_lock<std::mutex> sLock(sendMutex_);
461     sendCv_.notify_one();
462     sLock.unlock();
463     inputAvailQue_->SetActive(false, false);
464     sendTask_->Pause();
465 
466     if (sInfo_.surface != nullptr) {
467         renderAvailQue_->SetActive(false, false);
468     }
469     std::unique_lock<std::mutex> rLock(recvMutex_);
470     recvCv_.notify_one();
471     rLock.unlock();
472     codecAvailQue_->SetActive(false, false);
473     receiveTask_->Pause();
474 
475     avcodec_flush_buffers(avCodecContext_.get());
476     ResetContext(true);
477     ResetBuffers();
478     state_ = State::FLUSHED;
479     AVCODEC_LOGI("Flush codec successful, state: Flushed");
480     return AVCS_ERR_OK;
481 }
482 
Reset()483 int32_t FCodec::Reset()
484 {
485     AVCODEC_SYNC_TRACE;
486     AVCODEC_LOGI("Reset codec called");
487     int32_t ret = Release();
488     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot release codec");
489     ret = Initialize();
490     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Reset codec failed: cannot init codec");
491     AVCODEC_LOGI("Reset codec successful, state: Initialized");
492     return AVCS_ERR_OK;
493 }
494 
ReleaseResource()495 void FCodec::ReleaseResource()
496 {
497     StopThread();
498     if (avCodecContext_ != nullptr) {
499         avcodec_close(avCodecContext_.get());
500         ResetContext();
501     }
502     ReleaseBuffers();
503     format_ = Format();
504     if (sInfo_.surface != nullptr) {
505         sInfo_.surface->CleanCache();
506         AVCODEC_LOGI("surface cleancache success");
507         int ret = UnRegisterListenerToSurface(sInfo_.surface);
508         if (ret != 0) {
509             callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
510             state_ = State::ERROR;
511         }
512     }
513     sInfo_.surface = nullptr;
514 }
515 
Release()516 int32_t FCodec::Release()
517 {
518     AVCODEC_SYNC_TRACE;
519     state_ = State::STOPPING;
520     AVCODEC_LOGI("step into STOPPING status");
521     ReleaseResource();
522     state_ = State::UNINITIALIZED;
523     AVCODEC_LOGI("Release codec successful, state: Uninitialized");
524     return AVCS_ERR_OK;
525 }
526 
SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType)527 void FCodec::SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType)
528 {
529     CHECK_AND_RETURN_LOG(formatType == FORMAT_TYPE_INT32, "Set parameter failed: type should be int32");
530     int32_t val = 0;
531     CHECK_AND_RETURN_LOG(format.GetIntValue(formatKey, val), "Set parameter failed: get value fail");
532     if (formatKey == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
533         VideoPixelFormat vpf = static_cast<VideoPixelFormat>(val);
534         CHECK_AND_RETURN_LOG(vpf == VideoPixelFormat::RGBA || vpf == VideoPixelFormat::YUVI420 ||
535                                  vpf == VideoPixelFormat::NV12 || vpf == VideoPixelFormat::NV21,
536                              "Set parameter failed: pixel format value %{public}d invalid", val);
537         outputPixelFmt_ = vpf;
538         {
539             std::lock_guard<std::mutex> lock(formatMutex_);
540             format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, val);
541         }
542         GraphicPixelFormat surfacePixelFmt = TranslateSurfaceFormat(vpf);
543         std::lock_guard<std::mutex> sLock(surfaceMutex_);
544         sInfo_.requestConfig.format = surfacePixelFmt;
545     } else if (formatKey == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE) {
546         VideoRotation sr = static_cast<VideoRotation>(val);
547         CHECK_AND_RETURN_LOG(sr == VideoRotation::VIDEO_ROTATION_0 || sr == VideoRotation::VIDEO_ROTATION_90 ||
548                                  sr == VideoRotation::VIDEO_ROTATION_180 || sr == VideoRotation::VIDEO_ROTATION_270,
549                              "Set parameter failed: rotation angle value %{public}d invalid", val);
550         {
551             std::lock_guard<std::mutex> lock(formatMutex_);
552             format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val);
553         }
554         std::lock_guard<std::mutex> sLock(surfaceMutex_);
555         sInfo_.surface->SetTransform(TranslateSurfaceRotation(sr));
556     } else if (formatKey == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
557         ScalingMode scaleMode = static_cast<ScalingMode>(val);
558         CHECK_AND_RETURN_LOG(scaleMode == ScalingMode::SCALING_MODE_SCALE_TO_WINDOW ||
559                                  scaleMode == ScalingMode::SCALING_MODE_SCALE_CROP,
560                              "Set parameter failed: scale type value %{public}d invalid", val);
561         {
562             std::lock_guard<std::mutex> lock(formatMutex_);
563             format_.PutIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, val);
564         }
565         std::lock_guard<std::mutex> sLock(surfaceMutex_);
566         sInfo_.scalingMode = scaleMode;
567     } else {
568         AVCODEC_LOGW("Set parameter failed: %{public}s", std::string(formatKey).c_str());
569         return;
570     }
571     AVCODEC_LOGI("Set parameter %{public}s success, val %{public}d", std::string(formatKey).c_str(), val);
572 }
573 
SetParameter(const Format &format)574 int32_t FCodec::SetParameter(const Format &format)
575 {
576     AVCODEC_SYNC_TRACE;
577     for (auto &it : format.GetFormatMap()) {
578         if (sInfo_.surface != nullptr && it.second.type == FORMAT_TYPE_INT32) {
579             if (it.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT ||
580                 it.first == MediaDescriptionKey::MD_KEY_ROTATION_ANGLE ||
581                 it.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
582                 SetSurfaceParameter(format, it.first, it.second.type);
583             }
584         } else {
585             AVCODEC_LOGW("Current Version, %{public}s is not supported", it.first.data());
586         }
587     }
588     AVCODEC_LOGI("Set parameter successful");
589     return AVCS_ERR_OK;
590 }
591 
GetOutputFormat(Format &format)592 int32_t FCodec::GetOutputFormat(Format &format)
593 {
594     AVCODEC_SYNC_TRACE;
595     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_BITRATE)) {
596         if (avCodecContext_ != nullptr) {
597             format_.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, avCodecContext_->bit_rate);
598         }
599     }
600     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_FRAME_RATE)) {
601         if (avCodecContext_ != nullptr && avCodecContext_->framerate.den > 0) {
602             double value = static_cast<double>(avCodecContext_->framerate.num) /
603                            static_cast<double>(avCodecContext_->framerate.den);
604             format_.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, value);
605         }
606     }
607     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE)) {
608         int32_t stride = AlignUp(width_, VIDEO_ALIGN_SIZE);
609         int32_t maxInputSize = static_cast<int32_t>((stride * height_ * VIDEO_PIX_DEPTH_YUV) / UV_SCALE_FACTOR);
610         format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, maxInputSize);
611     }
612     {
613         std::lock_guard<std::mutex> lock(formatMutex_);
614         format = format_;
615     }
616     AVCODEC_LOGI("Get outputFormat successful");
617     return AVCS_ERR_OK;
618 }
619 
CalculateBufferSize()620 void FCodec::CalculateBufferSize()
621 {
622     int32_t stride = AlignUp(width_, VIDEO_ALIGN_SIZE);
623     outputBufferSize_ = static_cast<int32_t>((stride * height_ * VIDEO_PIX_DEPTH_YUV) / UV_SCALE_FACTOR);
624     inputBufferSize_ = std::max(VIDEO_MIN_BUFFER_SIZE, outputBufferSize_);
625     if (outputPixelFmt_ == VideoPixelFormat::RGBA) {
626         outputBufferSize_ = static_cast<int32_t>(stride * height_ * VIDEO_PIX_DEPTH_RGBA);
627     }
628     AVCODEC_LOGI("width = %{public}d, height = %{public}d, stride = %{public}d, Input buffer size = %{public}d, output "
629                  "buffer size=%{public}d",
630                  width_, height_, stride, inputBufferSize_, outputBufferSize_);
631 }
632 
AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize)633 int32_t FCodec::AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize)
634 {
635     int32_t valBufferCnt = 0;
636     for (int32_t i = 0; i < bufferCnt; i++) {
637         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
638         std::shared_ptr<AVAllocator> allocator =
639             AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
640         CHECK_AND_CONTINUE_LOG(allocator != nullptr, "input buffer %{public}d allocator is nullptr", i);
641         buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, inBufferSize);
642         CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr, "Allocate input buffer failed, index=%{public}d", i);
643         AVCODEC_LOGI("Allocate input buffer success: index=%{public}d, size=%{public}d", i,
644                      buf->avBuffer_->memory_->GetCapacity());
645         buffers_[INDEX_INPUT].emplace_back(buf);
646         valBufferCnt++;
647     }
648     if (valBufferCnt < DEFAULT_MIN_BUFFER_CNT) {
649         AVCODEC_LOGE("Allocate input buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
650         buffers_[INDEX_INPUT].clear();
651         return AVCS_ERR_NO_MEMORY;
652     }
653     return AVCS_ERR_OK;
654 }
655 
SetSurfaceCfg(int32_t bufferCnt)656 int32_t FCodec::SetSurfaceCfg(int32_t bufferCnt)
657 {
658     CHECK_AND_RETURN_RET_LOG(sInfo_.surface->SetQueueSize(bufferCnt) == OHOS::SurfaceError::SURFACE_ERROR_OK,
659                              AVCS_ERR_NO_MEMORY, "Surface set QueueSize=%{public}d failed", bufferCnt);
660     if (outputPixelFmt_ == VideoPixelFormat::UNKNOWN) {
661         format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::NV12));
662     }
663     int32_t val32 = 0;
664     format_.GetIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, val32);
665     GraphicPixelFormat surfacePixelFmt = TranslateSurfaceFormat(static_cast<VideoPixelFormat>(val32));
666     CHECK_AND_RETURN_RET_LOG(surfacePixelFmt != GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BUTT, AVCS_ERR_UNSUPPORT,
667                              "Failed to allocate output buffer: unsupported surface format");
668     sInfo_.requestConfig.width = width_;
669     sInfo_.requestConfig.height = height_;
670     sInfo_.requestConfig.format = surfacePixelFmt;
671 
672     format_.GetIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, val32);
673     sInfo_.scalingMode = static_cast<ScalingMode>(val32);
674     format_.GetIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, val32);
675     sInfo_.surface->SetTransform(TranslateSurfaceRotation(static_cast<VideoRotation>(val32)));
676     return AVCS_ERR_OK;
677 }
678 
AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize)679 int32_t FCodec::AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize)
680 {
681     int32_t valBufferCnt = 0;
682     if (sInfo_.surface) {
683         CHECK_AND_RETURN_RET_LOG(SetSurfaceCfg(bufferCnt) == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "SetSurfaceCfg failed");
684     }
685     for (int i = 0; i < bufferCnt; i++) {
686         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
687         if (sInfo_.surface == nullptr) {
688             std::shared_ptr<AVAllocator> allocator =
689                 AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
690             CHECK_AND_CONTINUE_LOG(allocator != nullptr, "output buffer %{public}d allocator is nullptr", i);
691             buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, outBufferSize);
692             AVCODEC_LOGI("Allocate output share buffer success: index=%{public}d, size=%{public}d", i,
693                          buf->avBuffer_->memory_->GetCapacity());
694         } else {
695             buf->sMemory_ = std::make_shared<FSurfaceMemory>(&sInfo_);
696             CHECK_AND_CONTINUE_LOG(buf->sMemory_->GetSurfaceBuffer() != nullptr,
697                                    "output surface memory %{public}d create fail", i);
698             outAVBuffer4Surface_.emplace_back(AVBuffer::CreateAVBuffer());
699             buf->avBuffer_ = AVBuffer::CreateAVBuffer(buf->sMemory_->GetBase(), buf->sMemory_->GetSize());
700             AVCODEC_LOGI("Allocate output surface buffer success: index=%{public}d, size=%{public}d, "
701                          "stride=%{public}d",
702                          i, buf->sMemory_->GetSize(), buf->sMemory_->GetSurfaceBufferStride());
703         }
704         CHECK_AND_CONTINUE_LOG(buf->avBuffer_ != nullptr, "Allocate output buffer failed, index=%{public}d", i);
705 
706         buf->width_ = width_;
707         buf->height_ = height_;
708         buffers_[INDEX_OUTPUT].emplace_back(buf);
709         valBufferCnt++;
710     }
711     if (valBufferCnt < DEFAULT_MIN_BUFFER_CNT) {
712         AVCODEC_LOGE("Allocate output buffer failed: only %{public}d buffer is allocated, no memory", valBufferCnt);
713         buffers_[INDEX_INPUT].clear();
714         buffers_[INDEX_OUTPUT].clear();
715         return AVCS_ERR_NO_MEMORY;
716     }
717     return AVCS_ERR_OK;
718 }
719 
AllocateBuffers()720 int32_t FCodec::AllocateBuffers()
721 {
722     AVCODEC_SYNC_TRACE;
723     CalculateBufferSize();
724     CHECK_AND_RETURN_RET_LOG(inputBufferSize_ > 0 && outputBufferSize_ > 0, AVCS_ERR_INVALID_VAL,
725                              "Allocate buffer with input size=%{public}d, output size=%{public}d failed",
726                              inputBufferSize_, outputBufferSize_);
727     if (sInfo_.surface != nullptr && isOutBufSetted_ == false) {
728         format_.PutIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, DEFAULT_OUT_SURFACE_CNT);
729     }
730     int32_t inputBufferCnt = 0;
731     int32_t outputBufferCnt = 0;
732     format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, inputBufferCnt);
733     format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, outputBufferCnt);
734     inputAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("inputAvailQue", inputBufferCnt);
735     codecAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("codecAvailQue", outputBufferCnt);
736     if (sInfo_.surface != nullptr) {
737         renderAvailQue_ = std::make_shared<BlockQueue<uint32_t>>("renderAvailQue", outputBufferCnt);
738     }
739     if (AllocateInputBuffer(inputBufferCnt, inputBufferSize_) == AVCS_ERR_NO_MEMORY ||
740         AllocateOutputBuffer(outputBufferCnt, outputBufferSize_) == AVCS_ERR_NO_MEMORY) {
741         return AVCS_ERR_NO_MEMORY;
742     }
743     AVCODEC_LOGI("Allocate buffers successful");
744     return AVCS_ERR_OK;
745 }
746 
UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType)747 int32_t FCodec::UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType)
748 {
749     int32_t curBufSize = buffers_[bufferType][index]->avBuffer_->memory_->GetCapacity();
750     if (bufferSize != curBufSize) {
751         std::shared_ptr<FBuffer> buf = std::make_shared<FBuffer>();
752         std::shared_ptr<AVAllocator> allocator =
753             AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
754         CHECK_AND_RETURN_RET_LOG(allocator != nullptr, AVCS_ERR_NO_MEMORY, "buffer %{public}d allocator is nullptr",
755                                  index);
756         buf->avBuffer_ = AVBuffer::CreateAVBuffer(allocator, bufferSize);
757         CHECK_AND_RETURN_RET_LOG(buf->avBuffer_ != nullptr, AVCS_ERR_NO_MEMORY,
758                                  "Buffer allocate failed, index=%{public}d", index);
759         AVCODEC_LOGI("update share buffer success: bufferType=%{public}u, index=%{public}d, size=%{public}d",
760                      bufferType, index, buf->avBuffer_->memory_->GetCapacity());
761 
762         if (bufferType == INDEX_INPUT) {
763             buf->owner_ = FBuffer::Owner::OWNED_BY_USER;
764         } else {
765             buf->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
766         }
767         buffers_[bufferType][index] = buf;
768     }
769     return AVCS_ERR_OK;
770 }
771 
UpdateSurfaceMemory(uint32_t index)772 int32_t FCodec::UpdateSurfaceMemory(uint32_t index)
773 {
774     AVCODEC_SYNC_TRACE;
775     std::unique_lock<std::mutex> oLock(outputMutex_);
776     std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
777     oLock.unlock();
778     if (width_ != outputBuffer->width_ || height_ != outputBuffer->height_) {
779         std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
780         surfaceMemory->SetNeedRender(false);
781         surfaceMemory->ReleaseSurfaceBuffer();
782         while (state_ == State::RUNNING) {
783             std::unique_lock<std::mutex> sLock(surfaceMutex_);
784             sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
785             sLock.unlock();
786             if (surfaceBuffer != nullptr) {
787                 break;
788             }
789             std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_REQ_TIME));
790         }
791 
792         outputBuffer->avBuffer_ =
793             AVBuffer::CreateAVBuffer(outputBuffer->sMemory_->GetBase(), outputBuffer->sMemory_->GetSize());
794         outputBuffer->width_ = width_;
795         outputBuffer->height_ = height_;
796     }
797 
798     return AVCS_ERR_OK;
799 }
800 
CheckFormatChange(uint32_t index, int width, int height)801 int32_t FCodec::CheckFormatChange(uint32_t index, int width, int height)
802 {
803     if (width_ != width || height_ != height) {
804         AVCODEC_LOGI("format change, width: %{public}d->%{public}d, height: %{public}d->%{public}d", width_, width,
805                      height_, height);
806         width_ = width;
807         height_ = height;
808         ResetData();
809         scale_ = nullptr;
810         CalculateBufferSize();
811         {
812             std::lock_guard<std::mutex> lock(formatMutex_);
813             format_.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, width_);
814             format_.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, height_);
815             format_.PutIntValue(OHOS::Media::Tag::VIDEO_STRIDE,
816                                 outputPixelFmt_ == VideoPixelFormat::RGBA ? width_ * VIDEO_PIX_DEPTH_RGBA : width_);
817             format_.PutIntValue(OHOS::Media::Tag::VIDEO_SLICE_HEIGHT, height_);
818             format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_WIDTH, width_);
819             format_.PutIntValue(OHOS::Media::Tag::VIDEO_PIC_HEIGHT, height_);
820         }
821         if (sInfo_.surface) {
822             std::lock_guard<std::mutex> sLock(surfaceMutex_);
823             sInfo_.requestConfig.width = width_;
824             sInfo_.requestConfig.height = height_;
825         }
826         callback_->OnOutputFormatChanged(format_);
827     }
828     if (sInfo_.surface == nullptr) {
829         std::lock_guard<std::mutex> oLock(outputMutex_);
830         CHECK_AND_RETURN_RET_LOG((UpdateBuffers(index, outputBufferSize_, INDEX_OUTPUT) == AVCS_ERR_OK),
831                                  AVCS_ERR_NO_MEMORY, "Update  output buffer failed, index=%{public}u", index);
832     } else {
833         CHECK_AND_RETURN_RET_LOG((UpdateSurfaceMemory(index) == AVCS_ERR_OK), AVCS_ERR_NO_MEMORY,
834                                  "Update buffer failed");
835     }
836     return AVCS_ERR_OK;
837 }
838 
ReleaseBuffers()839 void FCodec::ReleaseBuffers()
840 {
841     ResetData();
842     if (!isBufferAllocated_) {
843         return;
844     }
845 
846     inputAvailQue_->Clear();
847     std::unique_lock<std::mutex> iLock(inputMutex_);
848     buffers_[INDEX_INPUT].clear();
849     synIndex_ = std::nullopt;
850     iLock.unlock();
851 
852     std::unique_lock<std::mutex> oLock(outputMutex_);
853     codecAvailQue_->Clear();
854     if (sInfo_.surface != nullptr) {
855         renderAvailQue_->Clear();
856         renderSurfaceBufferMap_.clear();
857         for (uint32_t i = 0; i < buffers_[INDEX_OUTPUT].size(); i++) {
858             std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][i];
859             if (outputBuffer->owner_ == FBuffer::Owner::OWNED_BY_CODEC) {
860                 std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
861                 surfaceMemory->SetNeedRender(false);
862                 surfaceMemory->ReleaseSurfaceBuffer();
863                 outputBuffer->owner_ = FBuffer::Owner::OWNED_BY_SURFACE;
864             }
865         }
866     }
867     buffers_[INDEX_OUTPUT].clear();
868     outAVBuffer4Surface_.clear();
869     oLock.unlock();
870     isBufferAllocated_ = false;
871 }
872 
QueueInputBuffer(uint32_t index)873 int32_t FCodec::QueueInputBuffer(uint32_t index)
874 {
875     AVCODEC_SYNC_TRACE;
876     CHECK_AND_RETURN_RET_LOG(state_ == State::RUNNING, AVCS_ERR_INVALID_STATE,
877                              "Queue input buffer failed: not in Running state");
878     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_INPUT].size(), AVCS_ERR_INVALID_VAL,
879                              "Queue input buffer failed with bad index, index=%{public}u, buffer_size=%{public}zu",
880                              index, buffers_[INDEX_INPUT].size());
881     std::shared_ptr<FBuffer> inputBuffer = buffers_[INDEX_INPUT][index];
882     CHECK_AND_RETURN_RET_LOG(inputBuffer->owner_ == FBuffer::Owner::OWNED_BY_USER, AVCS_ERR_INVALID_OPERATION,
883                              "Queue input buffer failed: buffer with index=%{public}u is not available", index);
884 
885     inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
886     std::shared_ptr<AVBuffer> &inputAVBuffer = inputBuffer->avBuffer_;
887     if (synIndex_) {
888         const std::shared_ptr<AVBuffer> &curAVBuffer = buffers_[INDEX_INPUT][synIndex_.value()]->avBuffer_;
889         int32_t curAVBufferSize = curAVBuffer->memory_->GetSize();
890         int32_t inputAVBufferSize = inputAVBuffer->memory_->GetSize();
891         if ((curAVBufferSize + inputAVBufferSize <= curAVBuffer->memory_->GetCapacity()) &&
892             memcpy_s(curAVBuffer->memory_->GetAddr() + curAVBufferSize, inputAVBufferSize,
893                      inputAVBuffer->memory_->GetAddr(), inputAVBufferSize) == EOK) {
894             curAVBuffer->memory_->SetSize(curAVBufferSize + inputAVBufferSize);
895             curAVBuffer->flag_ = inputAVBuffer->flag_;
896             curAVBuffer->pts_ = inputAVBuffer->pts_;
897 
898             if (inputAVBuffer->flag_ != AVCODEC_BUFFER_FLAG_CODEC_DATA &&
899                 inputAVBuffer->flag_ != AVCODEC_BUFFER_FLAG_PARTIAL_FRAME) {
900                 inputAvailQue_->Push(synIndex_.value());
901                 synIndex_ = std::nullopt;
902             }
903             inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
904             callback_->OnInputBufferAvailable(index, inputAVBuffer);
905             return AVCS_ERR_OK;
906         } else {
907             AVCODEC_LOGE("packet size %{public}d over buffer size %{public}d", curAVBufferSize + inputAVBufferSize,
908                          curAVBuffer->memory_->GetCapacity());
909             callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY);
910             state_ = State::ERROR;
911             return AVCS_ERR_NO_MEMORY;
912         }
913     } else {
914         if ((inputAVBuffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) ||
915             (inputAVBuffer->flag_ == AVCODEC_BUFFER_FLAG_PARTIAL_FRAME)) {
916             synIndex_ = index;
917         } else {
918             inputAvailQue_->Push(index);
919         }
920     }
921 
922     return AVCS_ERR_OK;
923 }
924 
SendFrame()925 void FCodec::SendFrame()
926 {
927     CHECK_AND_RETURN_LOG(state_ != State::STOPPING && state_ != State::FLUSHING, "Invalid state");
928     if (state_ != State::RUNNING || isSendEos_) {
929         std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_DECODE_TIME));
930         return;
931     }
932     uint32_t index = inputAvailQue_->Front();
933     CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
934     std::shared_ptr<FBuffer> &inputBuffer = buffers_[INDEX_INPUT][index];
935     std::shared_ptr<AVBuffer> &inputAVBuffer = inputBuffer->avBuffer_;
936     if (inputAVBuffer->flag_ & AVCODEC_BUFFER_FLAG_EOS) {
937         avPacket_->data = nullptr;
938         avPacket_->size = 0;
939         avPacket_->pts = 0;
940         std::unique_lock<std::mutex> sendLock(sendMutex_);
941         isSendEos_ = true;
942         sendCv_.wait_for(sendLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
943         AVCODEC_LOGI("Send eos end");
944     } else {
945         avPacket_->data = inputAVBuffer->memory_->GetAddr();
946         avPacket_->size = static_cast<int32_t>(inputAVBuffer->memory_->GetSize());
947         avPacket_->pts = inputAVBuffer->pts_;
948     }
949     std::unique_lock<std::mutex> sLock(syncMutex_);
950     int ret = avcodec_send_packet(avCodecContext_.get(), avPacket_.get());
951     sLock.unlock();
952     if (ret == 0 || ret == AVERROR_INVALIDDATA) {
953         EXPECT_AND_LOGW(ret == AVERROR_INVALIDDATA, "ffmpeg ret = %{public}s", AVStrError(ret).c_str());
954         std::unique_lock<std::mutex> recvLock(recvMutex_);
955         recvCv_.notify_one();
956         recvLock.unlock();
957         inputAvailQue_->Pop();
958         inputBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
959 #ifdef BUILD_ENG_VERSION
960         if (dumpInFile_ && dumpInFile_->is_open()) {
961             dumpInFile_->write(reinterpret_cast<char *>(inputAVBuffer->memory_->GetAddr()),
962                                static_cast<int32_t>(inputAVBuffer->memory_->GetSize()));
963         }
964 #endif // BUILD_ENG_VERSION
965         callback_->OnInputBufferAvailable(index, inputAVBuffer);
966     } else if (ret == AVERROR(EAGAIN)) {
967         std::unique_lock<std::mutex> sendLock(sendMutex_);
968         isSendWait_ = true;
969         sendCv_.wait_for(sendLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
970     } else {
971         AVCODEC_LOGE("Cannot send frame to codec: ffmpeg ret = %{public}s", AVStrError(ret).c_str());
972         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
973         state_ = State::ERROR;
974     }
975 }
976 
FillFrameBuffer(const std::shared_ptr<FBuffer> &frameBuffer)977 int32_t FCodec::FillFrameBuffer(const std::shared_ptr<FBuffer> &frameBuffer)
978 {
979     VideoPixelFormat targetPixelFmt = outputPixelFmt_;
980     if (outputPixelFmt_ == VideoPixelFormat::UNKNOWN) {
981         targetPixelFmt = sInfo_.surface ? VideoPixelFormat::NV12 : ConvertPixelFormatFromFFmpeg(cachedFrame_->format);
982     }
983     AVPixelFormat ffmpegFormat = ConvertPixelFormatToFFmpeg(targetPixelFmt);
984     int32_t ret;
985     if (ffmpegFormat == static_cast<AVPixelFormat>(cachedFrame_->format)) {
986         for (int32_t i = 0; cachedFrame_->linesize[i] > 0; i++) {
987             scaleData_[i] = cachedFrame_->data[i];
988             scaleLineSize_[i] = cachedFrame_->linesize[i];
989         }
990     } else {
991         ret = ConvertVideoFrame(&scale_, cachedFrame_, scaleData_, scaleLineSize_, ffmpegFormat);
992         CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Scale video frame failed: %{public}d", ret);
993         isConverted_ = true;
994     }
995     {
996         std::lock_guard<std::mutex> lock(formatMutex_);
997         format_.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(targetPixelFmt));
998     }
999     std::shared_ptr<AVMemory> &bufferMemory = frameBuffer->avBuffer_->memory_;
1000     CHECK_AND_RETURN_RET_LOG(bufferMemory != nullptr, AVCS_ERR_INVALID_VAL, "bufferMemory is nullptr");
1001     bufferMemory->SetSize(0);
1002     if (sInfo_.surface) {
1003         struct SurfaceInfo surfaceInfo;
1004         surfaceInfo.surfaceStride = static_cast<uint32_t>(frameBuffer->sMemory_->GetSurfaceBufferStride());
1005         surfaceInfo.surfaceFence = frameBuffer->sMemory_->GetFence();
1006         surfaceInfo.scaleData = scaleData_;
1007         surfaceInfo.scaleLineSize = scaleLineSize_;
1008         ret = WriteSurfaceData(bufferMemory, surfaceInfo, format_);
1009     } else {
1010         ret = WriteBufferData(bufferMemory, scaleData_, scaleLineSize_, format_);
1011     }
1012     frameBuffer->avBuffer_->pts_ = cachedFrame_->pts;
1013     AVCODEC_LOGD("Fill frame buffer successful");
1014     return ret;
1015 }
1016 
FramePostProcess(std::shared_ptr<FBuffer> &frameBuffer, uint32_t index, int32_t status, int ret)1017 void FCodec::FramePostProcess(std::shared_ptr<FBuffer> &frameBuffer, uint32_t index, int32_t status, int ret)
1018 {
1019     if (status == AVCS_ERR_OK) {
1020         codecAvailQue_->Pop();
1021         frameBuffer->owner_ = FBuffer::Owner::OWNED_BY_USER;
1022         if (sInfo_.surface) {
1023             outAVBuffer4Surface_[index]->pts_ = frameBuffer->avBuffer_->pts_;
1024             outAVBuffer4Surface_[index]->flag_ = frameBuffer->avBuffer_->flag_;
1025         }
1026         if (ret == AVERROR_EOF) {
1027             std::unique_lock<std::mutex> sLock(syncMutex_);
1028             avcodec_flush_buffers(avCodecContext_.get());
1029             sLock.unlock();
1030         } else {
1031             if (isSendWait_) {
1032                 std::lock_guard<std::mutex> sLock(sendMutex_);
1033                 isSendWait_ = false;
1034                 sendCv_.notify_one();
1035             }
1036         }
1037         callback_->OnOutputBufferAvailable(index,
1038                                            sInfo_.surface ? outAVBuffer4Surface_[index] : frameBuffer->avBuffer_);
1039     } else if (status == AVCS_ERR_UNSUPPORT) {
1040         AVCODEC_LOGE("Recevie frame from codec failed: OnError");
1041         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT);
1042         state_ = State::ERROR;
1043     } else {
1044         AVCODEC_LOGE("Recevie frame from codec failed");
1045         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1046         state_ = State::ERROR;
1047     }
1048 }
1049 
DumpOutputBuffer()1050 void FCodec::DumpOutputBuffer()
1051 {
1052     AVCODEC_LOGD("cur decNum: %{public}u", decNum_);
1053     if (decNum_ == 0) {
1054         callback_->OnOutputFormatChanged(format_);
1055     }
1056     decNum_++;
1057 #ifdef BUILD_ENG_VERSION
1058     if (!dumpOutFile_ || !dumpOutFile_->is_open()) {
1059         return;
1060     }
1061     for (int32_t i = 0; i < cachedFrame_->height; i++) {
1062         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[0] + i * cachedFrame_->linesize[0]),
1063                             static_cast<int32_t>(cachedFrame_->width));
1064     }
1065     for (int32_t i = 0; i < cachedFrame_->height / 2; i++) { // 2
1066         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[1] + i * cachedFrame_->linesize[1]),
1067                             static_cast<int32_t>(cachedFrame_->width / 2)); // 2
1068     }
1069     for (int32_t i = 0; i < cachedFrame_->height / 2; i++) { // 2
1070         dumpOutFile_->write(reinterpret_cast<char *>(cachedFrame_->data[2] + i * cachedFrame_->linesize[2]),
1071                             static_cast<int32_t>(cachedFrame_->width / 2)); // 2
1072     }
1073 #endif // BUILD_ENG_VERSION
1074 }
1075 
ReceiveFrame()1076 void FCodec::ReceiveFrame()
1077 {
1078     if (state_ == State::STOPPING || state_ == State::FLUSHING) {
1079         return;
1080     } else if (state_ != State::RUNNING) {
1081         std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_TRY_DECODE_TIME));
1082         return;
1083     }
1084     auto index = codecAvailQue_->Front();
1085     CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1086     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1087     std::unique_lock<std::mutex> sLock(syncMutex_);
1088     int ret = avcodec_receive_frame(avCodecContext_.get(), cachedFrame_.get());
1089     sLock.unlock();
1090     int32_t status = AVCS_ERR_OK;
1091     CHECK_AND_RETURN_LOG(ret != AVERROR_INVALIDDATA, "ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1092     if (ret >= 0) {
1093         DumpOutputBuffer();
1094         if (CheckFormatChange(index, cachedFrame_->width, cachedFrame_->height) == AVCS_ERR_OK) {
1095             CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1096             frameBuffer = buffers_[INDEX_OUTPUT][index];
1097             status = FillFrameBuffer(frameBuffer);
1098         } else {
1099             CHECK_AND_RETURN_LOG(state_ == State::RUNNING, "Not in running state");
1100             callback_->OnError(AVCODEC_ERROR_EXTEND_START, AVCS_ERR_NO_MEMORY);
1101             return;
1102         }
1103         frameBuffer->avBuffer_->flag_ = AVCODEC_BUFFER_FLAG_NONE;
1104     } else if (ret == AVERROR_EOF) {
1105         AVCODEC_LOGI("Receive eos");
1106         frameBuffer->avBuffer_->flag_ = AVCODEC_BUFFER_FLAG_EOS;
1107         frameBuffer->avBuffer_->memory_->SetSize(0);
1108         state_ = State::EOS;
1109     } else if (ret == AVERROR(EAGAIN)) {
1110         std::unique_lock<std::mutex> sendLock(sendMutex_);
1111         if (isSendWait_ || isSendEos_) {
1112             isSendWait_ = false;
1113             sendCv_.notify_one();
1114         }
1115         sendLock.unlock();
1116         std::unique_lock<std::mutex> recvLock(recvMutex_);
1117         recvCv_.wait_for(recvLock, std::chrono::milliseconds(DEFAULT_DECODE_WAIT_TIME));
1118         return;
1119     } else {
1120         AVCODEC_LOGE("Cannot recv frame from codec: ffmpeg ret = %{public}s", AVStrError(ret).c_str());
1121         callback_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN);
1122         state_ = State::ERROR;
1123         return;
1124     }
1125     FramePostProcess(frameBuffer, index, status, ret);
1126 }
1127 
FindAvailIndex(uint32_t index)1128 void FCodec::FindAvailIndex(uint32_t index)
1129 {
1130     uint32_t curQueSize = renderAvailQue_->Size();
1131     for (uint32_t i = 0u; i < curQueSize; i++) {
1132         uint32_t num = renderAvailQue_->Pop();
1133         if (num == index) {
1134             break;
1135         } else {
1136             renderAvailQue_->Push(num);
1137         }
1138     }
1139 }
1140 
ReleaseOutputBuffer(uint32_t index)1141 int32_t FCodec::ReleaseOutputBuffer(uint32_t index)
1142 {
1143     AVCODEC_SYNC_TRACE;
1144     std::unique_lock<std::mutex> oLock(outputMutex_);
1145     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_OUTPUT].size(), AVCS_ERR_INVALID_VAL,
1146                              "Failed to release output buffer: invalid index");
1147     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1148     oLock.unlock();
1149     if (frameBuffer->owner_ == FBuffer::Owner::OWNED_BY_USER) {
1150         frameBuffer->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
1151         codecAvailQue_->Push(index);
1152         return AVCS_ERR_OK;
1153     } else {
1154         AVCODEC_LOGE("Release output buffer failed: check your index=%{public}u", index);
1155         return AVCS_ERR_INVALID_VAL;
1156     }
1157 }
1158 
FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> &surfaceMemory, uint32_t index)1159 int32_t FCodec::FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> &surfaceMemory, uint32_t index)
1160 {
1161     sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
1162     CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, AVCS_ERR_INVALID_VAL,
1163                              "Failed to update surface memory: surface buffer is NULL");
1164     OHOS::BufferFlushConfig flushConfig = {{0, 0, surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight()},
1165         outAVBuffer4Surface_[index]->pts_, -1};
1166     surfaceMemory->SetNeedRender(true);
1167     surfaceMemory->UpdateSurfaceBufferScaleMode();
1168     if (outAVBuffer4Surface_[index]->meta_->Find(OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP) !=
1169         outAVBuffer4Surface_[index]->meta_->end()) {
1170         outAVBuffer4Surface_[index]->meta_->Get<OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP>(
1171             flushConfig.desiredPresentTimestamp);
1172         outAVBuffer4Surface_[index]->meta_->Remove(OHOS::Media::Tag::VIDEO_DECODER_DESIRED_PRESENT_TIMESTAMP);
1173     }
1174     auto res = sInfo_.surface->FlushBuffer(surfaceBuffer, -1, flushConfig);
1175     if (res != OHOS::SurfaceError::SURFACE_ERROR_OK) {
1176         AVCODEC_LOGW("Failed to update surface memory: %{public}d", res);
1177         surfaceMemory->SetNeedRender(false);
1178         surfaceMemory->ReleaseSurfaceBuffer();
1179         return AVCS_ERR_UNKNOWN;
1180     }
1181     renderSurfaceBufferMap_[index] = std::make_pair(surfaceBuffer, flushConfig);
1182     surfaceMemory->ReleaseSurfaceBuffer();
1183     return AVCS_ERR_OK;
1184 }
1185 
RenderOutputBuffer(uint32_t index)1186 int32_t FCodec::RenderOutputBuffer(uint32_t index)
1187 {
1188     AVCODEC_SYNC_TRACE;
1189     CHECK_AND_RETURN_RET_LOG(sInfo_.surface != nullptr, AVCS_ERR_UNSUPPORT,
1190                              "RenderOutputBuffer fail, surface is nullptr");
1191     std::unique_lock<std::mutex> oLock(outputMutex_);
1192     CHECK_AND_RETURN_RET_LOG(index < buffers_[INDEX_OUTPUT].size(), AVCS_ERR_INVALID_VAL,
1193                              "Failed to render output buffer: invalid index");
1194     std::shared_ptr<FBuffer> frameBuffer = buffers_[INDEX_OUTPUT][index];
1195     oLock.unlock();
1196     std::lock_guard<std::mutex> sLock(surfaceMutex_);
1197     if (frameBuffer->owner_ == FBuffer::Owner::OWNED_BY_USER) {
1198         std::shared_ptr<FSurfaceMemory> surfaceMemory = frameBuffer->sMemory_;
1199         int32_t ret = FlushSurfaceMemory(surfaceMemory, index);
1200         if (ret != AVCS_ERR_OK) {
1201             AVCODEC_LOGW("Update surface memory failed: %{public}d", static_cast<int32_t>(ret));
1202         } else {
1203             AVCODEC_LOGD("Update surface memory successful");
1204         }
1205         frameBuffer->owner_ = FBuffer::Owner::OWNED_BY_SURFACE;
1206         renderAvailQue_->Push(index);
1207         AVCODEC_LOGD("render output buffer with index, index=%{public}u", index);
1208         return AVCS_ERR_OK;
1209     } else {
1210         AVCODEC_LOGE("Failed to render output buffer with bad index, index=%{public}u", index);
1211         return AVCS_ERR_INVALID_VAL;
1212     }
1213 }
1214 
ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface)1215 int32_t FCodec::ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface)
1216 {
1217     CHECK_AND_RETURN_RET_LOG(sInfo_.surface != nullptr, AV_ERR_OPERATE_NOT_PERMIT,
1218                              "Not support convert from AVBuffer Mode to Surface Mode");
1219     sptr<Surface> oldSurface = sInfo_.surface;
1220     uint64_t oldId = oldSurface->GetUniqueId();
1221     uint64_t newId = newSurface->GetUniqueId();
1222     AVCODEC_LOGI("surface %{public}" PRIu64 " -> %{public}" PRIu64 "", oldId, newId);
1223     if (oldId == newId) {
1224         return AVCS_ERR_OK;
1225     }
1226     GSError err = RegisterListenerToSurface(newSurface);
1227     CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, AVCS_ERR_UNKNOWN,
1228         "surface %{public}" PRIu64 ", RegisterListenerToSurface failed, GSError=%{public}d", newId, err);
1229     int32_t outputBufferCnt = 0;
1230     format_.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, outputBufferCnt);
1231     int32_t ret = SetQueueSize(newSurface, outputBufferCnt);
1232     if (ret != AVCS_ERR_OK) {
1233         UnRegisterListenerToSurface(newSurface);
1234         return ret;
1235     }
1236     std::unique_lock<std::mutex> sLock(surfaceMutex_);
1237     ret = SwitchBetweenSurface(newSurface);
1238     if (ret != AVCS_ERR_OK) {
1239         UnRegisterListenerToSurface(newSurface);
1240         sInfo_.surface = oldSurface;
1241         return ret;
1242     }
1243     sLock.unlock();
1244     return AVCS_ERR_OK;
1245 }
1246 
SetQueueSize(const sptr<Surface> &surface, uint32_t targetSize)1247 int32_t FCodec::SetQueueSize(const sptr<Surface> &surface, uint32_t targetSize)
1248 {
1249     int32_t err = surface->SetQueueSize(targetSize);
1250     if (err != 0) {
1251         AVCODEC_LOGE("surface %{public}" PRIu64 ", SetQueueSize to %{public}u failed, GSError=%{public}d",
1252             surface->GetUniqueId(), targetSize, err);
1253         return AVCS_ERR_UNKNOWN;
1254     }
1255     AVCODEC_LOGI("surface %{public}" PRIu64 ", SetQueueSize to %{public}u succ", surface->GetUniqueId(), targetSize);
1256     return AVCS_ERR_OK;
1257 }
1258 
SwitchBetweenSurface(const sptr<Surface> &newSurface)1259 int32_t FCodec::SwitchBetweenSurface(const sptr<Surface> &newSurface)
1260 {
1261     sptr<Surface> curSurface = sInfo_.surface;
1262     newSurface->Connect(); // cleancache will work only if the surface is connected by us
1263     newSurface->CleanCache(); // make sure new surface is empty
1264     std::vector<uint32_t> ownedBySurfaceBufferIndex;
1265     uint64_t newId = newSurface->GetUniqueId();
1266     for (uint32_t index = 0; index < buffers_[INDEX_OUTPUT].size(); index++) {
1267         if (buffers_[INDEX_OUTPUT][index]->sMemory_ == nullptr) {
1268             continue;
1269         }
1270         sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1271         if (buffers_[INDEX_OUTPUT][index]->owner_ == FBuffer::Owner::OWNED_BY_SURFACE) {
1272             if (renderSurfaceBufferMap_.count(index)) {
1273                 surfaceBuffer = renderSurfaceBufferMap_[index].first;
1274                 ownedBySurfaceBufferIndex.push_back(index);
1275             }
1276         } else {
1277             surfaceBuffer = buffers_[INDEX_OUTPUT][index]->sMemory_->GetSurfaceBuffer();
1278         }
1279         if (surfaceBuffer == nullptr) {
1280             AVCODEC_LOGE("Get old surface buffer error!");
1281             return AVCS_ERR_UNKNOWN;
1282         }
1283         int32_t err = newSurface->AttachBufferToQueue(surfaceBuffer);
1284         if (err != 0) {
1285             AVCODEC_LOGE("surface %{public}" PRIu64 ", AttachBufferToQueue(seq=%{public}u) failed, GSError=%{public}d",
1286                 newId, surfaceBuffer->GetSeqNum(), err);
1287             return AVCS_ERR_UNKNOWN;
1288         }
1289     }
1290     int32_t videoRotation = 0;
1291     format_.GetIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, videoRotation);
1292     sInfo_.surface->SetTransform(TranslateSurfaceRotation(static_cast<VideoRotation>(videoRotation)));
1293     int32_t scalingMode = 0;
1294     format_.GetIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE, scalingMode);
1295     sInfo_.scalingMode = static_cast<ScalingMode>(scalingMode);
1296     sInfo_.surface = newSurface;
1297 
1298     for (uint32_t index: ownedBySurfaceBufferIndex) {
1299         int32_t ret = RenderNewSurfaceWithOldBuffer(newSurface, index);
1300         if (ret != AVCS_ERR_OK) {
1301             return ret;
1302         }
1303     }
1304 
1305     int32_t ret = UnRegisterListenerToSurface(curSurface);
1306     if (ret != AVCS_ERR_OK) {
1307         return ret;
1308     }
1309 
1310     curSurface->CleanCache(true); // make sure old surface is empty and go black
1311     return AVCS_ERR_OK;
1312 }
1313 
RenderNewSurfaceWithOldBuffer(const sptr<Surface> &newSurface, uint32_t index)1314 int32_t FCodec::RenderNewSurfaceWithOldBuffer(const sptr<Surface> &newSurface, uint32_t index)
1315 {
1316     std::shared_ptr<FSurfaceMemory> surfaceMemory = buffers_[INDEX_OUTPUT][index]->sMemory_;
1317     sptr<SurfaceBuffer> surfaceBuffer = renderSurfaceBufferMap_[index].first;
1318     OHOS::BufferFlushConfig flushConfig = renderSurfaceBufferMap_[index].second;
1319     surfaceMemory->SetNeedRender(true);
1320     newSurface->SetScalingMode(surfaceBuffer->GetSeqNum(), sInfo_.scalingMode);
1321     auto res = newSurface->FlushBuffer(surfaceBuffer, -1, flushConfig);
1322     if (res != OHOS::SurfaceError::SURFACE_ERROR_OK) {
1323         AVCODEC_LOGE("Failed to update surface memory: %{public}d", res);
1324         surfaceMemory->SetNeedRender(false);
1325         return AVCS_ERR_UNKNOWN;
1326     }
1327     return AVCS_ERR_OK;
1328 }
1329 
RequestBufferFromConsumer()1330 void FCodec::RequestBufferFromConsumer()
1331 {
1332     auto index = renderAvailQue_->Front();
1333     std::shared_ptr<FBuffer> outputBuffer = buffers_[INDEX_OUTPUT][index];
1334     std::shared_ptr<FSurfaceMemory> surfaceMemory = outputBuffer->sMemory_;
1335     sptr<SurfaceBuffer> surfaceBuffer = surfaceMemory->GetSurfaceBuffer();
1336     if (surfaceBuffer == nullptr) {
1337         AVCODEC_LOGE("get buffer failed.");
1338         return;
1339     }
1340     auto queSize = renderAvailQue_->Size();
1341     uint32_t curIndex = 0;
1342     uint32_t i = 0;
1343     for (i = 0; i < queSize; i++) {
1344         curIndex = renderAvailQue_->Pop();
1345         if (surfaceMemory->GetBase() == buffers_[INDEX_OUTPUT][curIndex]->avBuffer_->memory_->GetAddr() &&
1346             surfaceMemory->GetSize() == buffers_[INDEX_OUTPUT][curIndex]->avBuffer_->memory_->GetCapacity()) {
1347             buffers_[INDEX_OUTPUT][index]->sMemory_ = buffers_[INDEX_OUTPUT][curIndex]->sMemory_;
1348             buffers_[INDEX_OUTPUT][curIndex]->sMemory_ = surfaceMemory;
1349             break;
1350         } else {
1351             renderAvailQue_->Push(curIndex);
1352         }
1353     }
1354     if (i == queSize) {
1355         curIndex = index;
1356         outputBuffer->avBuffer_ = AVBuffer::CreateAVBuffer(surfaceMemory->GetBase(), surfaceMemory->GetSize());
1357         outputBuffer->width_ = width_;
1358         outputBuffer->height_ = height_;
1359         FindAvailIndex(curIndex);
1360     }
1361     buffers_[INDEX_OUTPUT][curIndex]->owner_ = FBuffer::Owner::OWNED_BY_CODEC;
1362     codecAvailQue_->Push(curIndex);
1363     if (renderSurfaceBufferMap_.count(curIndex)) {
1364         renderSurfaceBufferMap_.erase(curIndex);
1365     }
1366     AVCODEC_LOGD("Request output buffer success, index = %{public}u, queSize=%{public}zu, i=%{public}d", curIndex,
1367                  queSize, i);
1368 }
1369 
BufferReleasedByConsumer(uint64_t surfaceId)1370 GSError FCodec::BufferReleasedByConsumer(uint64_t surfaceId)
1371 {
1372     CHECK_AND_RETURN_RET_LOG(state_ == State::RUNNING || state_ == State::EOS, GSERROR_NO_PERMISSION, "In valid state");
1373     std::lock_guard<std::mutex> sLock(surfaceMutex_);
1374     CHECK_AND_RETURN_RET_LOG(renderAvailQue_->Size() > 0, GSERROR_NO_BUFFER, "No available buffer");
1375     CHECK_AND_RETURN_RET_LOG(surfaceId == sInfo_.surface->GetUniqueId(), GSERROR_INVALID_ARGUMENTS,
1376                              "Ignore callback from old surface");
1377     RequestBufferFromConsumer();
1378     return GSERROR_OK;
1379 }
1380 
UnRegisterListenerToSurface(const sptr<Surface> &surface)1381 int32_t FCodec::UnRegisterListenerToSurface(const sptr<Surface> &surface)
1382 {
1383     GSError err = surface->UnRegisterReleaseListener();
1384     CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, AVCS_ERR_UNKNOWN,
1385                              "surface %{public}" PRIu64 ", UnRegisterReleaseListener failed, GSError=%{public}d",
1386                              surface->GetUniqueId(), err);
1387     return AVCS_ERR_OK;
1388 }
1389 
RegisterListenerToSurface(const sptr<Surface> &surface)1390 GSError FCodec::RegisterListenerToSurface(const sptr<Surface> &surface)
1391 {
1392     uint64_t surfaceId = surface->GetUniqueId();
1393     wptr<FCodec> wp = this;
1394     GSError err = surface->RegisterReleaseListener([wp, surfaceId](sptr<SurfaceBuffer> &) {
1395         sptr<FCodec> codec = wp.promote();
1396         if (!codec) {
1397             AVCODEC_LOGD("decoder is gone");
1398             return GSERROR_OK;
1399         }
1400         return codec->BufferReleasedByConsumer(surfaceId);
1401     });
1402     return err;
1403 }
1404 
SetOutputSurface(sptr<Surface> surface)1405 int32_t FCodec::SetOutputSurface(sptr<Surface> surface)
1406 {
1407     AVCODEC_SYNC_TRACE;
1408     CHECK_AND_RETURN_RET_LOG(state_ != State::UNINITIALIZED, AV_ERR_INVALID_VAL,
1409                              "set output surface fail: not initialized or configured");
1410     CHECK_AND_RETURN_RET_LOG((state_ == State::CONFIGURED || state_ == State::FLUSHED ||
1411         state_ == State::RUNNING || state_ == State::EOS), AVCS_ERR_INVALID_STATE,
1412         "set output surface fail: state %{public}d not support set output surface",
1413         static_cast<int32_t>(state_.load()));
1414     if (surface == nullptr || surface->IsConsumer()) {
1415         AVCODEC_LOGE("Set surface fail");
1416         return AVCS_ERR_INVALID_VAL;
1417     }
1418     if (state_ == State::FLUSHED || state_ == State::RUNNING || state_ == State::EOS) {
1419         return ReplaceOutputSurfaceWhenRunning(surface);
1420     }
1421     sInfo_.surface = surface;
1422     GSError err = RegisterListenerToSurface(sInfo_.surface);
1423     CHECK_AND_RETURN_RET_LOG(err == GSERROR_OK, AVCS_ERR_UNKNOWN,
1424                              "surface %{public}" PRIu64 ", RegisterListenerToSurface failed, GSError=%{public}d",
1425                              sInfo_.surface->GetUniqueId(), err);
1426     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_SCALE_TYPE)) {
1427         std::lock_guard<std::mutex> lock(formatMutex_);
1428         format_.PutIntValue(MediaDescriptionKey::MD_KEY_SCALE_TYPE,
1429                             static_cast<int32_t>(ScalingMode::SCALING_MODE_SCALE_TO_WINDOW));
1430     }
1431     if (!format_.ContainKey(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE)) {
1432         std::lock_guard<std::mutex> lock(formatMutex_);
1433         format_.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE,
1434                             static_cast<int32_t>(VideoRotation::VIDEO_ROTATION_0));
1435     }
1436     AVCODEC_LOGI("Set surface success");
1437     return AVCS_ERR_OK;
1438 }
1439 
SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)1440 int32_t FCodec::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
1441 {
1442     AVCODEC_SYNC_TRACE;
1443     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Set callback failed: callback is NULL");
1444     callback_ = callback;
1445     return AVCS_ERR_OK;
1446 }
1447 
GetCodecCapability(std::vector<CapabilityData> &capaArray)1448 int32_t FCodec::GetCodecCapability(std::vector<CapabilityData> &capaArray)
1449 {
1450     for (uint32_t i = 0; i < SUPPORT_VCODEC_NUM; ++i) {
1451         CapabilityData capsData;
1452         capsData.codecName = static_cast<std::string>(SUPPORT_VCODEC[i].codecName);
1453         capsData.mimeType = static_cast<std::string>(SUPPORT_VCODEC[i].mimeType);
1454         capsData.codecType = SUPPORT_VCODEC[i].isEncoder ? AVCODEC_TYPE_VIDEO_ENCODER : AVCODEC_TYPE_VIDEO_DECODER;
1455         capsData.isVendor = false;
1456         capsData.maxInstance = VIDEO_INSTANCE_SIZE;
1457         capsData.alignment.width = VIDEO_ALIGNMENT_SIZE;
1458         capsData.alignment.height = VIDEO_ALIGNMENT_SIZE;
1459         capsData.width.minVal = VIDEO_MIN_SIZE;
1460         capsData.width.maxVal = VIDEO_MAX_WIDTH_SIZE;
1461         capsData.height.minVal = VIDEO_MIN_SIZE;
1462         capsData.height.maxVal = VIDEO_MAX_HEIGHT_SIZE;
1463         capsData.frameRate.minVal = 0;
1464         capsData.frameRate.maxVal = VIDEO_FRAMERATE_MAX_SIZE;
1465         capsData.bitrate.minVal = 1;
1466         capsData.bitrate.maxVal = VIDEO_BITRATE_MAX_SIZE;
1467         capsData.blockPerFrame.minVal = 1;
1468         capsData.blockPerFrame.maxVal = VIDEO_BLOCKPERFRAME_SIZE;
1469         capsData.blockPerSecond.minVal = 1;
1470         capsData.blockPerSecond.maxVal = VIDEO_BLOCKPERSEC_SIZE;
1471         capsData.blockSize.width = VIDEO_ALIGN_SIZE;
1472         capsData.blockSize.height = VIDEO_ALIGN_SIZE;
1473         if (SUPPORT_VCODEC[i].isEncoder) {
1474             capsData.complexity.minVal = 0;
1475             capsData.complexity.maxVal = 0;
1476             capsData.encodeQuality.minVal = 0;
1477             capsData.encodeQuality.maxVal = 0;
1478         }
1479         capsData.pixFormat = {
1480             static_cast<int32_t>(VideoPixelFormat::YUVI420), static_cast<int32_t>(VideoPixelFormat::NV12),
1481             static_cast<int32_t>(VideoPixelFormat::NV21), static_cast<int32_t>(VideoPixelFormat::RGBA)};
1482         capsData.profiles = {static_cast<int32_t>(AVC_PROFILE_BASELINE), static_cast<int32_t>(AVC_PROFILE_MAIN),
1483                              static_cast<int32_t>(AVC_PROFILE_HIGH)};
1484         std::vector<int32_t> levels;
1485         for (int32_t j = 0; j <= static_cast<int32_t>(AVCLevel::AVC_LEVEL_51); ++j) {
1486             levels.emplace_back(j);
1487         }
1488         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_MAIN), levels));
1489         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_HIGH), levels));
1490         capsData.profileLevelsMap.insert(std::make_pair(static_cast<int32_t>(AVC_PROFILE_BASELINE), levels));
1491         capaArray.emplace_back(capsData);
1492     }
1493     return AVCS_ERR_OK;
1494 }
1495 } // namespace Codec
1496 } // namespace MediaAVCodec
1497 } // namespace OHOS
1498