• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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