1 /*
2 * Copyright (c) 2024-2024 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 "video_encoder.h"
17 #include <cstdint>
18 #include <string>
19 #include <unordered_map>
20 #include "frame_record.h"
21 #include "surface_type.h"
22 #include "external_window.h"
23 #include "avcodec_common.h"
24 #include "native_avbuffer.h"
25 #include "utils/camera_log.h"
26 #include <chrono>
27 #include <fcntl.h>
28 #include <cinttypes>
29 #include <unistd.h>
30 #include <memory>
31 #include <sync_fence.h>
32 #include "native_mfmagic.h"
33 #include "media_description.h"
34
35 namespace OHOS {
36 namespace CameraStandard {
37
~VideoEncoder()38 VideoEncoder::~VideoEncoder()
39 {
40 MEDIA_INFO_LOG("~VideoEncoder enter");
41 Release();
42 }
43
VideoEncoder(VideoCodecType type,ColorSpace colorSpace)44 VideoEncoder::VideoEncoder(VideoCodecType type, ColorSpace colorSpace) : videoCodecType_(type),
45 isHdr_(IsHdr(colorSpace))
46 {
47 MEDIA_INFO_LOG("VideoEncoder enter");
48 }
49
IsHdr(ColorSpace colorSpace)50 bool VideoEncoder::IsHdr(ColorSpace colorSpace)
51 {
52 std::vector<ColorSpace> hdrColorSpaces = {BT2020_HLG, BT2020_PQ, BT2020_HLG_LIMIT,
53 BT2020_PQ_LIMIT};
54 auto it = std::find(hdrColorSpaces.begin(), hdrColorSpaces.end(), colorSpace);
55 return it != hdrColorSpaces.end();
56 }
57
Create(const std::string & codecMime)58 int32_t VideoEncoder::Create(const std::string &codecMime)
59 {
60 std::lock_guard<std::mutex> lock(encoderMutex_);
61 avCodecProxy_ = AVCodecProxy::CreateAVCodecProxy();
62 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
63 auto ret = avCodecProxy_->CreateAVCodecVideoEncoder(codecMime);
64 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Create AVCodecVideoEncoder failed, ret: %{public}d", ret);
65 return 0;
66 }
67
Config()68 int32_t VideoEncoder::Config()
69 {
70 std::lock_guard<std::mutex> lock(encoderMutex_);
71 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
72 std::unique_lock<std::mutex> contextLock(contextMutex_);
73 context_ = new VideoCodecUserData;
74 // Configure video encoder
75 int32_t ret = Configure();
76 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Configure failed");
77 // SetCallback for video encoder
78 ret = SetCallback();
79 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Set callback failed");
80 contextLock.unlock();
81 return 0;
82 }
83
Start()84 int32_t VideoEncoder::Start()
85 {
86 std::lock_guard<std::mutex> lock(encoderMutex_);
87 // Prepare video encoder
88 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
89 int ret = avCodecProxy_->AVCodecVideoEncoderPrepare();
90 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Prepare failed, ret: %{public}d", ret);
91 // Start video encoder
92 ret = avCodecProxy_->AVCodecVideoEncoderStart();
93 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Start failed, ret: %{public}d", ret);
94 isStarted_ = true;
95 return 0;
96 }
97
GetSurface()98 int32_t VideoEncoder::GetSurface()
99 {
100 std::lock_guard<std::mutex> lock(encoderMutex_);
101 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
102 std::lock_guard<std::mutex> surfaceLock(surfaceMutex_);
103 codecSurface_ = avCodecProxy_->CreateInputSurface();
104 CHECK_RETURN_RET_ELOG(codecSurface_ == nullptr, 1, "Surface is null");
105 return 0;
106 }
107
ReleaseSurfaceBuffer(sptr<FrameRecord> frameRecord)108 int32_t VideoEncoder::ReleaseSurfaceBuffer(sptr<FrameRecord> frameRecord)
109 {
110 CAMERA_SYNC_TRACE;
111 CHECK_RETURN_RET_ELOG(frameRecord->GetSurfaceBuffer() == nullptr, 1,
112 "SurfaceBuffer is released %{public}s", frameRecord->GetFrameId().c_str());
113 sptr<SurfaceBuffer> releaseBuffer;
114 int32_t ret = DetachCodecBuffer(releaseBuffer, frameRecord);
115 CHECK_RETURN_RET_ELOG(ret != SURFACE_ERROR_OK, ret, " %{public}s ReleaseSurfaceBuffer failed",
116 frameRecord->GetFrameId().c_str());
117 frameRecord->SetSurfaceBuffer(releaseBuffer);
118 // after request surfaceBuffer
119 frameRecord->NotifyBufferRelease();
120 MEDIA_INFO_LOG("release codec surface buffer end");
121 return 0;
122 }
123
DetachCodecBuffer(sptr<SurfaceBuffer> & surfaceBuffer,sptr<FrameRecord> frameRecord)124 int32_t VideoEncoder::DetachCodecBuffer(sptr<SurfaceBuffer> &surfaceBuffer, sptr<FrameRecord> frameRecord)
125 {
126 CHECK_RETURN_RET_ELOG(frameRecord == nullptr, 1, "frameRecord is null");
127 std::lock_guard<std::mutex> lock(surfaceMutex_);
128 CHECK_RETURN_RET_ELOG(codecSurface_ == nullptr, 1, "codecSurface_ is null");
129 sptr<SyncFence> syncFence = SyncFence::INVALID_FENCE;
130 BufferRequestConfig requestConfig = {
131 .width = frameRecord->GetFrameSize()->width,
132 .height = frameRecord->GetFrameSize()->height,
133 .strideAlignment = 0x8, // default stride is 8 Bytes.
134 .format = frameRecord->GetFormat(),
135 .usage = frameRecord->GetUsage(),
136 .timeout = 0,
137 };
138 SurfaceError ret = codecSurface_->RequestBuffer(surfaceBuffer, syncFence, requestConfig);
139 CHECK_RETURN_RET_ELOG(ret != SURFACE_ERROR_OK, ret, "RequestBuffer failed. %{public}d", ret);
140 constexpr uint32_t waitForEver = -1;
141 (void)syncFence->Wait(waitForEver);
142 CHECK_RETURN_RET_ELOG(surfaceBuffer == nullptr, ret, "Failed to request codec Buffer");
143 ret = codecSurface_->DetachBufferFromQueue(surfaceBuffer);
144 CHECK_RETURN_RET_ELOG(ret != SURFACE_ERROR_OK, ret, "Failed to detach buffer %{public}d", ret);
145 return ret;
146 }
147
PushInputData(sptr<CodecAVBufferInfo> info)148 int32_t VideoEncoder::PushInputData(sptr<CodecAVBufferInfo> info)
149 {
150 // LCOV_EXCL_START
151 std::lock_guard<std::mutex> lock(encoderMutex_);
152 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
153 int32_t ret = AV_ERR_OK;
154 ret = OH_AVBuffer_SetBufferAttr(info->buffer, &info->attr);
155 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Set avbuffer attr failed, ret: %{public}d", ret);
156 ret = avCodecProxy_->QueueInputBuffer(info->bufferIndex);
157 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Push input data failed, ret: %{public}d", ret);
158 return 0;
159 // LCOV_EXCL_STOP
160 }
161
NotifyEndOfStream()162 int32_t VideoEncoder::NotifyEndOfStream()
163 {
164 std::lock_guard<std::mutex> lock(encoderMutex_);
165 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
166 int32_t ret = avCodecProxy_->AVCodecVideoEncoderNotifyEos();
167 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1,
168 "Notify end of stream failed, ret: %{public}d", ret);
169 return 0;
170 }
171
FreeOutputData(uint32_t bufferIndex)172 int32_t VideoEncoder::FreeOutputData(uint32_t bufferIndex)
173 {
174 // LCOV_EXCL_START
175 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
176 int32_t ret = avCodecProxy_->ReleaseOutputBuffer(bufferIndex);
177 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1,
178 "Free output data failed, ret: %{public}d", ret);
179 return 0;
180 // LCOV_EXCL_STOP
181 }
182
Stop()183 int32_t VideoEncoder::Stop()
184 {
185 CAMERA_SYNC_TRACE;
186 std::lock_guard<std::mutex> lock(encoderMutex_);
187 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
188 int32_t ret = avCodecProxy_->AVCodecVideoEncoderStop();
189 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Stop failed, ret: %{public}d", ret);
190 isStarted_ = false;
191 return 0;
192 }
193
SetVideoCodec(const std::shared_ptr<Size> & size,int32_t rotation)194 void VideoEncoder::SetVideoCodec(const std::shared_ptr<Size>& size, int32_t rotation)
195 {
196 MEDIA_INFO_LOG("VideoEncoder SetVideoCodec E videoCodecType_ = %{public}d", videoCodecType_);
197 size_ = size;
198 rotation_ = rotation;
199 videoCodecType_ = VideoCodecType::VIDEO_ENCODE_TYPE_HEVC;
200 Create(MIME_VIDEO_HEVC.data());
201 Config();
202 GetSurface();
203 MEDIA_INFO_LOG("VideoEncoder SetVideoCodec X");
204 }
205
RestartVideoCodec(shared_ptr<Size> size,int32_t rotation)206 void VideoEncoder::RestartVideoCodec(shared_ptr<Size> size, int32_t rotation)
207 {
208 // LCOV_EXCL_START
209 Release();
210 size_ = size;
211 rotation_ = rotation;
212 MEDIA_INFO_LOG("VideoEncoder videoCodecType_ = %{public}d", videoCodecType_);
213 if (videoCodecType_ == VideoCodecType::VIDEO_ENCODE_TYPE_AVC) {
214 Create(MIME_VIDEO_AVC.data());
215 } else if (videoCodecType_ == VideoCodecType::VIDEO_ENCODE_TYPE_HEVC) {
216 Create(MIME_VIDEO_HEVC.data());
217 }
218 Config();
219 GetSurface();
220 Start();
221 // LCOV_EXCL_STOP
222 }
223
EnqueueBuffer(sptr<FrameRecord> frameRecord,int32_t keyFrameInterval)224 bool VideoEncoder::EnqueueBuffer(sptr<FrameRecord> frameRecord, int32_t keyFrameInterval)
225 {
226 // LCOV_EXCL_START
227 CHECK_EXECUTE(!isStarted_ || avCodecProxy_ == nullptr || size_ == nullptr,
228 RestartVideoCodec(frameRecord->GetFrameSize(), frameRecord->GetRotation()));
229 if (keyFrameInterval == KEY_FRAME_INTERVAL) {
230 std::lock_guard<std::mutex> lock(encoderMutex_);
231 MediaAVCodec::Format format = MediaAVCodec::Format();
232 format.PutIntValue(MediaDescriptionKey::MD_KEY_REQUEST_I_FRAME, true);
233 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, false, "avCodecProxy_ is nullptr");
234 int32_t ret = avCodecProxy_->AVCodecVideoEncoderSetParameter(format);
235 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, false, "SetParameter failed, ret: %{public}d", ret);
236 }
237 sptr<SurfaceBuffer> buffer = frameRecord->GetSurfaceBuffer();
238 CHECK_RETURN_RET_ELOG(buffer == nullptr, false, "Enqueue video buffer is empty");
239 std::lock_guard<std::mutex> lock(surfaceMutex_);
240 CHECK_RETURN_RET_ELOG(codecSurface_ == nullptr, false, "codecSurface_ is null");
241 SurfaceError surfaceRet = codecSurface_->AttachBufferToQueue(buffer);
242 if (surfaceRet != SURFACE_ERROR_OK) {
243 MEDIA_ERR_LOG("Failed to attach buffer, surfaceRet: %{public}d", surfaceRet);
244 // notify release buffer when attach failed
245 frameRecord->NotifyBufferRelease();
246 return false;
247 }
248 constexpr int32_t invalidFence = -1;
249 BufferFlushConfig flushConfig = {
250 .damage = {
251 .w = buffer->GetWidth(),
252 .h = buffer->GetHeight(),
253 },
254 .timestamp = frameRecord->GetTimeStamp(),
255 };
256 surfaceRet = codecSurface_->FlushBuffer(buffer, invalidFence, flushConfig);
257 CHECK_RETURN_RET_ELOG(surfaceRet != 0, false, "FlushBuffer failed");
258 MEDIA_DEBUG_LOG("Success frame id is : %{public}s", frameRecord->GetFrameId().c_str());
259 return true;
260 // LCOV_EXCL_STOP
261 }
262
ProcessFrameRecord(sptr<VideoCodecAVBufferInfo> bufferInfo,sptr<FrameRecord> frameRecord)263 bool VideoEncoder::ProcessFrameRecord(sptr<VideoCodecAVBufferInfo> bufferInfo, sptr<FrameRecord> frameRecord)
264 {
265 MEDIA_DEBUG_LOG("enter VideoEncoder::ProcessFrameRecord");
266 if (bufferInfo->buffer->flag_ == AVCODEC_BUFFER_FLAGS_CODEC_DATA) {
267 // first return IDR frame
268 std::shared_ptr<Media::AVBuffer> IDRBuffer = bufferInfo->GetCopyAVBuffer();
269 frameRecord->CacheBuffer(IDRBuffer);
270 frameRecord->SetIDRProperty(true);
271 successFrame_ = false;
272 return true;
273 } else if (bufferInfo->buffer->flag_ == AVCODEC_BUFFER_FLAGS_SYNC_FRAME) {
274 // then return I frame
275 std::shared_ptr<Media::AVBuffer> tempBuffer = bufferInfo->AddCopyAVBuffer(frameRecord->encodedBuffer);
276 if (tempBuffer != nullptr) {
277 frameRecord->encodedBuffer = tempBuffer;
278 }
279 successFrame_ = true;
280 return true;
281 } else if (bufferInfo->buffer->flag_ == AVCODEC_BUFFER_FLAGS_NONE) {
282 // return P frame
283 std::shared_ptr<Media::AVBuffer> PBuffer = bufferInfo->GetCopyAVBuffer();
284 frameRecord->CacheBuffer(PBuffer);
285 frameRecord->SetIDRProperty(false);
286 successFrame_ = true;
287 return true;
288 } else {
289 return false;
290 }
291 }
292
EncodeSurfaceBuffer(sptr<FrameRecord> frameRecord)293 bool VideoEncoder::EncodeSurfaceBuffer(sptr<FrameRecord> frameRecord)
294 {
295 // LCOV_EXCL_START
296 if (frameRecord->GetTimeStamp() - preFrameTimestamp_ > NANOSEC_RANGE) {
297 keyFrameInterval_ = KEY_FRAME_INTERVAL;
298 } else {
299 keyFrameInterval_ = (keyFrameInterval_ == 0 ? KEY_FRAME_INTERVAL : keyFrameInterval_);
300 }
301 preFrameTimestamp_ = frameRecord->GetTimeStamp();
302 CHECK_RETURN_RET(!EnqueueBuffer(frameRecord, keyFrameInterval_), false);
303 keyFrameInterval_--;
304 int32_t retryCount = 5;
305 while (retryCount > 0) {
306 retryCount--;
307 std::unique_lock<std::mutex> contextLock(contextMutex_);
308 CHECK_RETURN_RET_ELOG(context_ == nullptr, false, "VideoEncoder has been released");
309 std::unique_lock<std::mutex> lock(context_->outputMutex_);
310 bool condRet = context_->outputCond_.wait_for(lock, std::chrono::milliseconds(BUFFER_ENCODE_EXPIREATION_TIME),
311 [this]() { return !isStarted_ || !context_->outputBufferInfoQueue_.empty(); });
312 CHECK_CONTINUE_WLOG(context_->outputBufferInfoQueue_.empty(),
313 "Buffer queue is empty, continue, cond ret: %{public}d", condRet);
314 sptr<VideoCodecAVBufferInfo> bufferInfo = context_->outputBufferInfoQueue_.front();
315 MEDIA_INFO_LOG("Out buffer count: %{public}u, size: %{public}d, flag: %{public}u, pts:%{public}" PRIu64 ", "
316 "timestamp:%{public}" PRIu64, context_->outputFrameCount_, bufferInfo->buffer->memory_->GetSize(),
317 bufferInfo->buffer->flag_, bufferInfo->buffer->pts_, frameRecord->GetTimeStamp());
318 context_->outputBufferInfoQueue_.pop();
319 context_->outputFrameCount_++;
320 lock.unlock();
321 contextLock.unlock();
322 std::lock_guard<std::mutex> encodeLock(encoderMutex_);
323 CHECK_RETURN_RET_ELOG(!isStarted_ || avCodecProxy_ == nullptr || !avCodecProxy_->IsVideoEncoderExisted(),
324 false, "EncodeSurfaceBuffer when encoder stop!");
325 condRet = ProcessFrameRecord(bufferInfo, frameRecord);
326 if (condRet == false) {
327 MEDIA_ERR_LOG("Flag is not acceptted number: %{public}u", bufferInfo->buffer->flag_);
328 int32_t ret = FreeOutputData(bufferInfo->bufferIndex);
329 CHECK_BREAK_WLOG(ret != 0, "FreeOutputData failed");
330 continue;
331 }
332 int32_t ret = FreeOutputData(bufferInfo->bufferIndex);
333 CHECK_BREAK_WLOG(ret != 0, "FreeOutputData failed");
334 if (successFrame_) {
335 MEDIA_DEBUG_LOG("Success frame id is : %{public}s, refCount: %{public}d",
336 frameRecord->GetFrameId().c_str(), frameRecord->GetSptrRefCount());
337 return true;
338 }
339 }
340 MEDIA_ERR_LOG("Failed frame id is : %{public}s", frameRecord->GetFrameId().c_str());
341 return false;
342 // LCOV_EXCL_STOP
343 }
344
Release()345 int32_t VideoEncoder::Release()
346 {
347 {
348 std::lock_guard<std::mutex> lock(encoderMutex_);
349 CHECK_EXECUTE(avCodecProxy_ && avCodecProxy_->IsVideoEncoderExisted(),
350 avCodecProxy_->AVCodecVideoEncoderRelease());
351 avCodecProxy_.reset();
352 }
353 std::unique_lock<std::mutex> contextLock(contextMutex_);
354 isStarted_ = false;
355 return 0;
356 }
357
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)358 void VideoEncoder::CallBack::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
359 {
360 (void)errorCode;
361 MEDIA_ERR_LOG("On decoder error, error code: %{public}d", errorCode);
362 }
363
OnOutputFormatChanged(const Format & format)364 void VideoEncoder::CallBack::OnOutputFormatChanged(const Format &format)
365 {
366 MEDIA_ERR_LOG("OnCodecFormatChange");
367 }
368
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)369 void VideoEncoder::CallBack::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
370 {
371 MEDIA_DEBUG_LOG("OnInputBufferAvailable");
372 }
373
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)374 void VideoEncoder::CallBack::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
375 {
376 // LCOV_EXCL_START
377 MEDIA_DEBUG_LOG("OnOutputBufferAvailable");
378 auto encoder = videoEncoder_.lock();
379 CHECK_RETURN_ELOG(encoder == nullptr, "encoder is nullptr");
380 CHECK_RETURN_ELOG(encoder->context_ == nullptr, "encoder context is nullptr");
381 std::unique_lock<std::mutex> lock(encoder->context_->outputMutex_);
382 encoder->context_->outputBufferInfoQueue_.emplace(new VideoCodecAVBufferInfo(index, buffer));
383 encoder->context_->outputCond_.notify_all();
384 // LCOV_EXCL_STOP
385 }
386
SetCallback()387 int32_t VideoEncoder::SetCallback()
388 {
389 // LCOV_EXCL_START
390 int32_t ret = AV_ERR_OK;
391 auto callback = make_shared<CallBack>(weak_from_this());
392 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
393 ret = avCodecProxy_->AVCodecVideoEncoderSetCallback(callback);
394 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Set callback failed, ret: %{public}d", ret);
395 return 0;
396 // LCOV_EXCL_STOP
397 }
398
Configure()399 int32_t VideoEncoder::Configure()
400 {
401 MediaAVCodec::Format format = MediaAVCodec::Format();
402 int32_t bitrate = static_cast<int32_t>(pow(float(size_->width) * float(size_->height) / DEFAULT_SIZE,
403 VIDEO_BITRATE_CONSTANT) * BITRATE_22M);
404 bitrate_ = videoCodecType_ == VideoCodecType::VIDEO_ENCODE_TYPE_AVC
405 ? static_cast<int32_t>(bitrate * HEVC_TO_AVC_FACTOR) : bitrate;
406 MEDIA_INFO_LOG("Current resolution is : %{public}d*%{public}d, encode type : %{public}d, set bitrate : %{public}d",
407 size_->width, size_->height, videoCodecType_, bitrate_);
408 format.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, size_->width);
409 format.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, size_->height);
410 format.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, rotation_);
411 format.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, VIDEO_FRAME_RATE);
412 format.PutIntValue(MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, MediaAVCodec::SQR);
413 format.PutLongValue(MediaDescriptionKey::MD_KEY_BITRATE, bitrate_);
414 format.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, VIDOE_PIXEL_FORMAT);
415 format.PutIntValue(MediaDescriptionKey::MD_KEY_I_FRAME_INTERVAL, INT_MAX);
416 if (videoCodecType_ == VideoCodecType::VIDEO_ENCODE_TYPE_HEVC && isHdr_) {
417 format.PutIntValue(MediaDescriptionKey::MD_KEY_PROFILE, MediaAVCodec::HEVC_PROFILE_MAIN_10);
418 }
419 CHECK_RETURN_RET_ELOG(avCodecProxy_ == nullptr, 1, "avCodecProxy_ is nullptr");
420 int ret = avCodecProxy_->AVCodecVideoEncoderConfigure(format);
421 CHECK_RETURN_RET_ELOG(ret != AV_ERR_OK, 1, "Config failed, ret: %{public}d", ret);
422 return 0;
423 }
424
GetEncoderBitrate()425 int32_t VideoEncoder::GetEncoderBitrate()
426 {
427 return bitrate_;
428 }
429 } // CameraStandard
430 } // OHOS