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