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