• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "surface_encoder_adapter.h"
17 #include <ctime>
18 #include "avcodec_info.h"
19 #include "avcodec_common.h"
20 #include "codec_server.h"
21 #include "meta/format.h"
22 #include "media_description.h"
23 #include "native_avcapability.h"
24 #include "native_avcodec_base.h"
25 #include "avcodec_trace.h"
26 #include "avcodec_sysevent.h"
27 #include "common/log.h"
28 
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "SurfaceEncoderAdapter" };
31 }
32 
33 constexpr uint32_t TIME_OUT_MS = 1000;
34 constexpr uint32_t NS_PER_US = 1000;
35 constexpr int64_t SEC_TO_NS = 1000000000;
36 namespace OHOS {
37 namespace Media {
38 
39 using namespace OHOS::MediaAVCodec;
40 class SurfaceEncoderAdapterCallback : public MediaAVCodec::MediaCodecCallback {
41 public:
SurfaceEncoderAdapterCallback(std::shared_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter)42     explicit SurfaceEncoderAdapterCallback(std::shared_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter)
43         : surfaceEncoderAdapter_(std::move(surfaceEncoderAdapter))
44     {
45     }
46 
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)47     void OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode) override
48     {
49         if (auto surfaceEncoderAdapter = surfaceEncoderAdapter_.lock()) {
50             surfaceEncoderAdapter->encoderAdapterCallback_->OnError(errorType, errorCode);
51         } else {
52             MEDIA_LOG_I("invalid surfaceEncoderAdapter");
53         }
54     }
55 
OnOutputFormatChanged(const MediaAVCodec::Format & format)56     void OnOutputFormatChanged(const MediaAVCodec::Format &format) override
57     {
58     }
59 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)60     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
61     {
62     }
63 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)64     void OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
65     {
66         if (auto surfaceEncoderAdapter = surfaceEncoderAdapter_.lock()) {
67             surfaceEncoderAdapter->OnOutputBufferAvailable(index, buffer);
68         } else {
69             MEDIA_LOG_I("invalid surfaceEncoderAdapter");
70         }
71     }
72 
73 private:
74     std::weak_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter_;
75 };
76 
77 class DroppedFramesCallback : public MediaAVCodec::MediaCodecParameterWithAttrCallback {
78 public:
DroppedFramesCallback(std::shared_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter)79     explicit DroppedFramesCallback(std::shared_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter)
80         : surfaceEncoderAdapter_(std::move(surfaceEncoderAdapter))
81     {
82     }
83 
OnInputParameterWithAttrAvailable(uint32_t index,std::shared_ptr<Format> attribute,std::shared_ptr<Format> parameter)84     void OnInputParameterWithAttrAvailable(uint32_t index, std::shared_ptr<Format> attribute,
85         std::shared_ptr<Format> parameter) override
86     {
87         if (auto surfaceEncoderAdapter = surfaceEncoderAdapter_.lock()) {
88             surfaceEncoderAdapter->OnInputParameterWithAttrAvailable(index, attribute, parameter);
89         } else {
90             MEDIA_LOG_I("invalid surfaceEncoderAdapter");
91         }
92     }
93 
94 private:
95     std::weak_ptr<SurfaceEncoderAdapter> surfaceEncoderAdapter_;
96 };
97 
SurfaceEncoderAdapter()98 SurfaceEncoderAdapter::SurfaceEncoderAdapter()
99 {
100     MEDIA_LOG_I("encoder adapter create");
101 }
102 
~SurfaceEncoderAdapter()103 SurfaceEncoderAdapter::~SurfaceEncoderAdapter()
104 {
105     MEDIA_LOG_I("encoder adapter destroy");
106     if (codecServer_) {
107         codecServer_->Release();
108     }
109     codecServer_ = nullptr;
110 }
111 
Init(const std::string & mime,bool isEncoder)112 Status SurfaceEncoderAdapter::Init(const std::string &mime, bool isEncoder)
113 {
114     MEDIA_LOG_I("Init mime: " PUBLIC_LOG_S, mime.c_str());
115     codecMimeType_ = mime;
116     Format format;
117     std::shared_ptr<Media::Meta> callerInfo = std::make_shared<Media::Meta>();
118     callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_PID, appPid_);
119     callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_UID, appUid_);
120     callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_PROCESS_NAME, bundleName_);
121     format.SetMeta(callerInfo);
122     int32_t ret = MediaAVCodec::VideoEncoderFactory::CreateByMime(mime, format, codecServer_);
123     MEDIA_LOG_I("AVCodecVideoEncoderImpl::Init CreateByMime errorCode %{public}d", ret);
124     if (!codecServer_) {
125         MEDIA_LOG_I("Create codecServer failed");
126         SetFaultEvent("SurfaceEncoderAdapter::Init Create codecServer failed", ret);
127         return Status::ERROR_UNKNOWN;
128     }
129     if (!releaseBufferTask_) {
130         releaseBufferTask_ = std::make_shared<Task>("SurfaceEncoder");
131         releaseBufferTask_->RegisterJob([this] {
132             ReleaseBuffer();
133             return 0;
134         });
135     }
136     return Status::OK;
137 }
138 
ConfigureGeneralFormat(MediaAVCodec::Format & format,const std::shared_ptr<Meta> & meta)139 void SurfaceEncoderAdapter::ConfigureGeneralFormat(MediaAVCodec::Format &format, const std::shared_ptr<Meta> &meta)
140 {
141     MEDIA_LOG_I("ConfigureGeneralFormat");
142     if (meta->Find(Tag::VIDEO_WIDTH) != meta->end()) {
143         int32_t videoWidth;
144         meta->Get<Tag::VIDEO_WIDTH>(videoWidth);
145         format.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, videoWidth);
146     }
147     if (meta->Find(Tag::VIDEO_HEIGHT) != meta->end()) {
148         int32_t videoHeight;
149         meta->Get<Tag::VIDEO_HEIGHT>(videoHeight);
150         format.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, videoHeight);
151     }
152     if (meta->Find(Tag::VIDEO_CAPTURE_RATE) != meta->end()) {
153         double videoCaptureRate;
154         meta->Get<Tag::VIDEO_CAPTURE_RATE>(videoCaptureRate);
155         format.PutDoubleValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CAPTURE_RATE, videoCaptureRate);
156     }
157     if (meta->Find(Tag::MEDIA_BITRATE) != meta->end()) {
158         int64_t mediaBitrate;
159         meta->Get<Tag::MEDIA_BITRATE>(mediaBitrate);
160         format.PutLongValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE, mediaBitrate);
161     }
162     if (meta->Find(Tag::VIDEO_FRAME_RATE) != meta->end()) {
163         double videoFrameRate;
164         meta->Get<Tag::VIDEO_FRAME_RATE>(videoFrameRate);
165         format.PutDoubleValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_FRAME_RATE, videoFrameRate);
166     }
167     if (meta->Find(Tag::MIME_TYPE) != meta->end()) {
168         std::string mimeType;
169         meta->Get<Tag::MIME_TYPE>(mimeType);
170         format.PutStringValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME, mimeType);
171     }
172     if (meta->Find(Tag::VIDEO_H265_PROFILE) != meta->end()) {
173         Plugins::HEVCProfile h265Profile;
174         meta->Get<Tag::VIDEO_H265_PROFILE>(h265Profile);
175         format.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_PROFILE, h265Profile);
176     }
177 }
178 
ConfigureEnableFormat(MediaAVCodec::Format & format,const std::shared_ptr<Meta> & meta)179 void SurfaceEncoderAdapter::ConfigureEnableFormat(MediaAVCodec::Format &format, const std::shared_ptr<Meta> &meta)
180 {
181     MEDIA_LOG_I("ConfigureEnableFormat");
182     if (meta->Find(Tag::VIDEO_ENCODER_ENABLE_WATERMARK) != meta->end()) {
183         bool enableWatermark = false;
184         meta->Get<Tag::VIDEO_ENCODER_ENABLE_WATERMARK>(enableWatermark);
185         format.PutIntValue(Tag::VIDEO_ENCODER_ENABLE_WATERMARK, enableWatermark);
186     }
187 }
188 
Configure(const std::shared_ptr<Meta> & meta)189 Status SurfaceEncoderAdapter::Configure(const std::shared_ptr<Meta> &meta)
190 {
191     MEDIA_LOG_I("Configure");
192     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Configure");
193     MediaAVCodec::Format format = MediaAVCodec::Format();
194     ConfigureGeneralFormat(format, meta);
195     ConfigureAboutRGBA(format, meta);
196     ConfigureAboutEnableTemporalScale(format, meta);
197     ConfigureEnableFormat(format, meta);
198     if (!codecServer_) {
199         SetFaultEvent("SurfaceEncoderAdapter::Configure, CodecServer is null");
200         return Status::ERROR_UNKNOWN;
201     }
202     int32_t ret = static_cast<int32_t>(Status::OK);
203     if (!isTransCoderMode) {
204         std::shared_ptr<MediaAVCodec::MediaCodecParameterWithAttrCallback> droppedFramesCallback =
205         std::make_shared<DroppedFramesCallback>(shared_from_this());
206         ret = codecServer_->SetCallback(droppedFramesCallback);
207         if (ret != 0) {
208             MEDIA_LOG_I("Set dropped Frames Callback failed");
209             SetFaultEvent("DroppedFramesCallback::DroppedFramesCallback error", ret);
210             return Status::ERROR_UNKNOWN;
211         }
212     }
213     if (isTransCoderMode) {
214         format.PutIntValue(Tag::VIDEO_FRAME_RATE_ADAPTIVE_MODE, true);
215     }
216     ret = codecServer_->Configure(format);
217     if (ret != 0) {
218         SetFaultEvent("SurfaceEncoderAdapter::Configure error", ret);
219     }
220     return ret == 0 ? Status::OK : Status::ERROR_UNKNOWN;
221 }
222 
SetWatermark(std::shared_ptr<AVBuffer> & waterMarkBuffer)223 Status SurfaceEncoderAdapter::SetWatermark(std::shared_ptr<AVBuffer> &waterMarkBuffer)
224 {
225     MEDIA_LOG_I("SetWaterMark");
226     if (!codecServer_) {
227         MEDIA_LOG_I("CodecServer is null");
228         SetFaultEvent("SurfaceEncoderAdapter::setWatermark, CodecServer is null");
229         return Status::ERROR_UNKNOWN;
230     }
231     int ret = codecServer_->SetCustomBuffer(waterMarkBuffer);
232     if (ret != 0) {
233         MEDIA_LOG_E("SetCustomBuffer error");
234         return Status::ERROR_UNKNOWN;
235     }
236     return Status::OK;
237 }
238 
SetOutputBufferQueue(const sptr<AVBufferQueueProducer> & bufferQueueProducer)239 Status SurfaceEncoderAdapter::SetOutputBufferQueue(const sptr<AVBufferQueueProducer> &bufferQueueProducer)
240 {
241     MEDIA_LOG_I("SetOutputBufferQueue");
242     outputBufferQueueProducer_ = bufferQueueProducer;
243     return Status::OK;
244 }
245 
SetEncoderAdapterCallback(const std::shared_ptr<EncoderAdapterCallback> & encoderAdapterCallback)246 Status SurfaceEncoderAdapter::SetEncoderAdapterCallback(
247     const std::shared_ptr<EncoderAdapterCallback> &encoderAdapterCallback)
248 {
249     MEDIA_LOG_I("SetEncoderAdapterCallback");
250     std::shared_ptr<MediaAVCodec::MediaCodecCallback> surfaceEncoderAdapterCallback =
251         std::make_shared<SurfaceEncoderAdapterCallback>(shared_from_this());
252     encoderAdapterCallback_ = encoderAdapterCallback;
253     if (!codecServer_) {
254         SetFaultEvent("SurfaceEncoderAdapter::SetEncoderAdapterCallback, CodecServer is null");
255         return Status::ERROR_UNKNOWN;
256     }
257     int32_t ret = codecServer_->SetCallback(surfaceEncoderAdapterCallback);
258     if (ret == 0) {
259         return Status::OK;
260     } else {
261         SetFaultEvent("SurfaceEncoderAdapter::SetEncoderAdapterCallback error", ret);
262         return Status::ERROR_UNKNOWN;
263     }
264 }
265 
SetEncoderAdapterKeyFramePtsCallback(const std::shared_ptr<EncoderAdapterKeyFramePtsCallback> & encoderAdapterKeyFramePtsCallback)266 Status SurfaceEncoderAdapter::SetEncoderAdapterKeyFramePtsCallback(
267     const std::shared_ptr<EncoderAdapterKeyFramePtsCallback> &encoderAdapterKeyFramePtsCallback)
268 {
269     MEDIA_LOG_I("SetEncoderAdapterKeyFramePtsCallback");
270     encoderAdapterKeyFramePtsCallback_ = encoderAdapterKeyFramePtsCallback;
271     return Status::OK;
272 }
273 
SetInputSurface(sptr<Surface> surface)274 Status SurfaceEncoderAdapter::SetInputSurface(sptr<Surface> surface)
275 {
276     MEDIA_LOG_I("GetInputSurface");
277     if (!codecServer_) {
278         SetFaultEvent("SurfaceEncoderAdapter::SetInputSurface, CodecServer is null");
279         return Status::ERROR_UNKNOWN;
280     }
281     MediaAVCodec::CodecServer *codecServerPtr = (MediaAVCodec::CodecServer *)(codecServer_.get());
282     int32_t ret = codecServerPtr->SetInputSurface(surface);
283     if (ret == 0) {
284         return Status::OK;
285     } else {
286         SetFaultEvent("SurfaceEncoderAdapter::SetInputSurface error", ret);
287         return Status::ERROR_UNKNOWN;
288     }
289 }
290 
SetTransCoderMode()291 Status SurfaceEncoderAdapter::SetTransCoderMode()
292 {
293     MEDIA_LOG_I("SetTransCoderMode");
294     isTransCoderMode = true;
295     return Status::OK;
296 }
297 
GetInputSurface()298 sptr<Surface> SurfaceEncoderAdapter::GetInputSurface()
299 {
300     FALSE_RETURN_V_MSG(codecServer_ != nullptr, nullptr, "codecServer_ is nullptr");
301     return codecServer_->CreateInputSurface();
302 }
303 
Start()304 Status SurfaceEncoderAdapter::Start()
305 {
306     MEDIA_LOG_I("Start");
307     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Start");
308     if (!codecServer_) {
309         SetFaultEvent("SurfaceEncoderAdapter::Start, CodecServer is null");
310         return Status::ERROR_UNKNOWN;
311     }
312     int32_t ret;
313     isThreadExit_ = false;
314     if (releaseBufferTask_) {
315         releaseBufferTask_->Start();
316     }
317     ret = codecServer_->Start();
318     isStart_ = true;
319     isStartKeyFramePts_ = true;
320     if (ret == 0) {
321         return Status::OK;
322     } else {
323         SetFaultEvent("SurfaceEncoderAdapter::Start error", ret);
324         return Status::ERROR_UNKNOWN;
325     }
326 }
327 
Stop()328 Status SurfaceEncoderAdapter::Stop()
329 {
330     MEDIA_LOG_I("Stop");
331     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Stop");
332     GetCurrentTime(stopTime_);
333     isStopKeyFramePts_ = true;
334     MEDIA_LOG_I("Stop time: " PUBLIC_LOG_D64, stopTime_);
335 
336     if (isStart_ && !isTransCoderMode) {
337         std::unique_lock<std::mutex> lock(stopMutex_);
338         stopCondition_.wait_for(lock, std::chrono::milliseconds(TIME_OUT_MS));
339         AddStopPts();
340     }
341     if (releaseBufferTask_) {
342         isThreadExit_ = true;
343         releaseBufferCondition_.notify_all();
344         releaseBufferTask_->Stop();
345         MEDIA_LOG_I("releaseBufferTask_ Stop");
346     }
347     if (!codecServer_) {
348         return Status::OK;
349     }
350     int32_t ret = codecServer_->Stop();
351     MEDIA_LOG_I("codecServer_ Stop");
352     isStart_ = false;
353     if (ret == 0) {
354         return Status::OK;
355     } else {
356         SetFaultEvent("SurfaceEncoderAdapter::Stop error", ret);
357         return Status::ERROR_UNKNOWN;
358     }
359 }
360 
Pause()361 Status SurfaceEncoderAdapter::Pause()
362 {
363     MEDIA_LOG_I("Pause");
364     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Pause");
365     if (isTransCoderMode) {
366         return Status::OK;
367     }
368     std::lock_guard<std::mutex> lock(checkFramesMutex_);
369     int64_t pauseTime = 0;
370     GetCurrentTime(pauseTime);
371     MEDIA_LOG_I("Pause time: " PUBLIC_LOG_D64, pauseTime);
372     if (pauseResumeQueue_.empty() ||
373         (pauseResumeQueue_.back().second == StateCode::RESUME && pauseResumeQueue_.back().first <= pauseTime)) {
374         pauseResumeQueue_.push_back({pauseTime, StateCode::PAUSE});
375         pauseResumeQueue_.push_back({std::numeric_limits<int64_t>::max(), StateCode::RESUME});
376         pauseResumePts_.push_back({pauseTime, StateCode::PAUSE});
377         pauseResumePts_.push_back({std::numeric_limits<int64_t>::max(), StateCode::RESUME});
378     }
379     return Status::OK;
380 }
381 
Resume()382 Status SurfaceEncoderAdapter::Resume()
383 {
384     MEDIA_LOG_I("Resume");
385     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Resume");
386     if (isTransCoderMode) {
387         isResume_ = true;
388         return Status::OK;
389     }
390     std::lock_guard<std::mutex> lock(checkFramesMutex_);
391     int64_t resumeTime = 0;
392     GetCurrentTime(resumeTime);
393     MEDIA_LOG_I("resume time: " PUBLIC_LOG_D64, resumeTime);
394     if (pauseResumeQueue_.empty()) {
395         MEDIA_LOG_I("Status Error, no pause before resume");
396         return Status::ERROR_UNKNOWN;
397     }
398     if (pauseResumeQueue_.back().second == StateCode::RESUME) {
399         pauseResumeQueue_.back().first = std::min(resumeTime, pauseResumeQueue_.back().first);
400         pauseResumePts_.back().first = std::min(resumeTime, pauseResumePts_.back().first);
401     }
402     return Status::OK;
403 }
404 
Flush()405 Status SurfaceEncoderAdapter::Flush()
406 {
407     MEDIA_LOG_I("Flush");
408     if (!codecServer_) {
409         SetFaultEvent("SurfaceEncoderAdapter::Flush, CodecServer is null");
410         return Status::ERROR_UNKNOWN;
411     }
412     int32_t ret = codecServer_->Flush();
413     if (ret == 0) {
414         return Status::OK;
415     } else {
416         SetFaultEvent("SurfaceEncoderAdapter::Flush error", ret);
417         return Status::ERROR_UNKNOWN;
418     }
419 }
420 
Reset()421 Status SurfaceEncoderAdapter::Reset()
422 {
423     MEDIA_LOG_I("Reset");
424     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Reset");
425     if (!codecServer_) {
426         return Status::OK;
427     }
428     int32_t ret = codecServer_->Reset();
429     startBufferTime_ = -1;
430     stopTime_ = -1;
431     totalPauseTime_ = 0;
432     isStart_ = false;
433     isStartKeyFramePts_ = false;
434     mappingTimeQueue_.clear();
435     pauseResumeQueue_.clear();
436     pauseResumePts_.clear();
437     if (ret == 0) {
438         return Status::OK;
439     } else {
440         SetFaultEvent("SurfaceEncoderAdapter::Reset error", ret);
441         return Status::ERROR_UNKNOWN;
442     }
443 }
444 
Release()445 Status SurfaceEncoderAdapter::Release()
446 {
447     MEDIA_LOG_I("Release");
448     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::Release");
449     if (!codecServer_) {
450         return Status::OK;
451     }
452     int32_t ret = codecServer_->Release();
453     if (ret == 0) {
454         return Status::OK;
455     } else {
456         SetFaultEvent("SurfaceEncoderAdapter::Release error", ret);
457         return Status::ERROR_UNKNOWN;
458     }
459 }
460 
NotifyEos(int64_t pts)461 Status SurfaceEncoderAdapter::NotifyEos(int64_t pts)
462 {
463     MEDIA_LOG_I("NotifyEos");
464     if (!codecServer_) {
465         SetFaultEvent("SurfaceEncoderAdapter::NotifyEos, CodecServer is null");
466         return Status::ERROR_UNKNOWN;
467     }
468     int32_t ret = 0;
469     MEDIA_LOG_I("lastBuffer PTS: " PUBLIC_LOG_D64, pts);
470     eosPts_ = pts;
471     if (!isTransCoderMode || currentPts_.load() >= eosPts_.load()) {
472         ret = codecServer_->NotifyEos();
473     }
474     if (ret == 0) {
475         return Status::OK;
476     } else {
477         SetFaultEvent("SurfaceEncoderAdapter::NotifyEos error", ret);
478         return Status::ERROR_UNKNOWN;
479     }
480 }
481 
SetParameter(const std::shared_ptr<Meta> & parameter)482 Status SurfaceEncoderAdapter::SetParameter(const std::shared_ptr<Meta> &parameter)
483 {
484     MEDIA_LOG_I("SetParameter");
485     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::SetParameter");
486     if (!codecServer_) {
487         SetFaultEvent("SurfaceEncoderAdapter::SetParameter, CodecServer is null");
488         return Status::ERROR_UNKNOWN;
489     }
490     MediaAVCodec::Format format = MediaAVCodec::Format();
491     int32_t ret = codecServer_->SetParameter(format);
492     if (ret == 0) {
493         return Status::OK;
494     } else {
495         SetFaultEvent("SurfaceEncoderAdapter::SetParameter error", ret);
496         return Status::ERROR_UNKNOWN;
497     }
498 }
499 
GetOutputFormat()500 std::shared_ptr<Meta> SurfaceEncoderAdapter::GetOutputFormat()
501 {
502     MEDIA_LOG_I("GetOutputFormat is not supported");
503     return nullptr;
504 }
505 
TransCoderOnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)506 void SurfaceEncoderAdapter::TransCoderOnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
507 {
508     if (buffer->pts_ >= eosPts_.load() && codecServer_) {
509         codecServer_->NotifyEos();
510     }
511     int32_t size = buffer->memory_->GetSize();
512     std::shared_ptr<AVBuffer> emptyOutputBuffer;
513     AVBufferConfig avBufferConfig;
514     avBufferConfig.size = size;
515     avBufferConfig.memoryType = MemoryType::SHARED_MEMORY;
516     avBufferConfig.memoryFlag = MemoryFlag::MEMORY_READ_WRITE;
517     Status status = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS);
518     if (status != Status::OK) {
519         MEDIA_LOG_I("RequestBuffer fail.");
520         return;
521     }
522     std::shared_ptr<AVMemory> &bufferMem = emptyOutputBuffer->memory_;
523     if (emptyOutputBuffer->memory_ == nullptr) {
524         MEDIA_LOG_I("emptyOutputBuffer->memory_ is nullptr");
525         return;
526     }
527     bufferMem->Write(buffer->memory_->GetAddr(), size, 0);
528     *(emptyOutputBuffer->meta_) = *(buffer->meta_);
529     emptyOutputBuffer->pts_ = buffer->pts_;
530     emptyOutputBuffer->flag_ = buffer->flag_;
531     outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, true);
532     {
533         std::lock_guard<std::mutex> lock(releaseBufferMutex_);
534         indexs_.push_back(index);
535     }
536     releaseBufferCondition_.notify_all();
537     MEDIA_LOG_D("OnOutputBufferAvailable end");
538 }
539 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)540 void SurfaceEncoderAdapter::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
541 {
542     MEDIA_LOG_D("OnOutputBufferAvailable buffer->pts" PUBLIC_LOG_D64, buffer->pts_);
543     currentPts_ = currentPts_.load() < buffer->pts_? buffer->pts_ : currentPts_.load();
544     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::OnOutputBufferAvailable");
545     if (isTransCoderMode) {
546         TransCoderOnOutputBufferAvailable(index, buffer);
547         return;
548     }
549     if (stopTime_ != -1 && buffer->pts_ > stopTime_) {
550         MEDIA_LOG_I("buffer->pts > stopTime, ready to stop");
551         std::unique_lock<std::mutex> lock(stopMutex_);
552         stopCondition_.notify_all();
553     }
554 
555     int64_t mappingTime = -1;
556     if (!(buffer->flag_ & AVCODEC_BUFFER_FLAG_CODEC_DATA)) {
557         std::lock_guard<std::mutex> mappingLock(mappingPtsMutex_);
558         if (mappingTimeQueue_.empty() || mappingTimeQueue_.front().first != buffer->pts_) {
559             MEDIA_LOG_D("buffer->pts fail");
560         } else {
561             mappingTime = mappingTimeQueue_.front().second;
562             mappingTimeQueue_.pop_front();
563         }
564         if (startBufferTime_ == -1) {
565             startBufferTime_ = buffer->pts_;
566         }
567         // cache recent 2 pts
568         preKeyFramePts_ = currentKeyFramePts_;
569         currentKeyFramePts_ = buffer->pts_;
570         AddStartPts(buffer->pts_);
571         AddPauseResumePts(buffer->pts_);
572     } else {
573         MEDIA_LOG_D("OnOutputBufferAvailable buffer->flag_" PUBLIC_LOG_U32, buffer->flag_);
574         mappingTime = startBufferTime_ + buffer->pts_;
575     }
576     int32_t size = buffer->memory_->GetSize();
577     std::shared_ptr<AVBuffer> emptyOutputBuffer;
578     AVBufferConfig avBufferConfig;
579     avBufferConfig.size = size;
580     avBufferConfig.memoryType = MemoryType::SHARED_MEMORY;
581     avBufferConfig.memoryFlag = MemoryFlag::MEMORY_READ_WRITE;
582     Status status = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS);
583     FALSE_RETURN_MSG(status == Status::OK, "RequestBuffer fail.");
584     std::shared_ptr<AVMemory> &bufferMem = emptyOutputBuffer->memory_;
585     FALSE_RETURN_MSG(emptyOutputBuffer->memory_ != nullptr, "emptyOutputBuffer->memory_ is nullptr");
586     bufferMem->Write(buffer->memory_->GetAddr(), size, 0);
587     *(emptyOutputBuffer->meta_) = *(buffer->meta_);
588     emptyOutputBuffer->pts_ = (mappingTime - startBufferTime_) / NS_PER_US;
589     emptyOutputBuffer->flag_ = buffer->flag_;
590     outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, true);
591     {
592         std::lock_guard<std::mutex> lock(releaseBufferMutex_);
593         indexs_.push_back(index);
594     }
595     releaseBufferCondition_.notify_all();
596 }
597 
ReleaseBuffer()598 void SurfaceEncoderAdapter::ReleaseBuffer()
599 {
600     MEDIA_LOG_I("ReleaseBuffer");
601     while (true) {
602         if (isThreadExit_) {
603             MEDIA_LOG_I("Exit ReleaseBuffer thread.");
604             break;
605         }
606         std::vector<uint32_t> indexs;
607         {
608             std::unique_lock<std::mutex> lock(releaseBufferMutex_);
609             releaseBufferCondition_.wait(lock, [this] {
610                 return isThreadExit_ || !indexs_.empty();
611             });
612             indexs = indexs_;
613             indexs_.clear();
614         }
615         for (auto &index : indexs) {
616             codecServer_->ReleaseOutputBuffer(index);
617         }
618     }
619     MEDIA_LOG_I("ReleaseBuffer end");
620 }
621 
ConfigureAboutRGBA(MediaAVCodec::Format & format,const std::shared_ptr<Meta> & meta)622 void SurfaceEncoderAdapter::ConfigureAboutRGBA(MediaAVCodec::Format &format, const std::shared_ptr<Meta> &meta)
623 {
624     Plugins::VideoPixelFormat pixelFormat = Plugins::VideoPixelFormat::NV12;
625     if (meta->Find(Tag::VIDEO_PIXEL_FORMAT) != meta->end()) {
626         meta->Get<Tag::VIDEO_PIXEL_FORMAT>(pixelFormat);
627     }
628     format.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, static_cast<int32_t>(pixelFormat));
629 
630     if (meta->Find(Tag::VIDEO_ENCODE_BITRATE_MODE) != meta->end()) {
631         Plugins::VideoEncodeBitrateMode videoEncodeBitrateMode;
632         meta->Get<Tag::VIDEO_ENCODE_BITRATE_MODE>(videoEncodeBitrateMode);
633         format.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_VIDEO_ENCODE_BITRATE_MODE, videoEncodeBitrateMode);
634     }
635 }
636 
ConfigureAboutEnableTemporalScale(MediaAVCodec::Format & format,const std::shared_ptr<Meta> & meta)637 void SurfaceEncoderAdapter::ConfigureAboutEnableTemporalScale(MediaAVCodec::Format &format,
638     const std::shared_ptr<Meta> &meta)
639 {
640     if (meta->Find(Tag::VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY) != meta->end()) {
641         bool enableTemporalScale;
642         meta->Get<Tag::VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY>(enableTemporalScale);
643         if (!enableTemporalScale) {
644             MEDIA_LOG_I("video encoder enableTemporalScale is false!");
645             return;
646         }
647 
648         bool isSupported = true;
649         if (isSupported) {
650             MEDIA_LOG_I("VIDEO_ENCODER_TEMPORAL_SCALABILITY is supported!");
651             format.PutIntValue(MediaAVCodec::MediaDescriptionKey::OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY,
652                 1);
653         } else {
654             MEDIA_LOG_I("VIDEO_ENCODER_TEMPORAL_SCALABILITY is not supported!");
655         }
656     }
657 }
658 
SetFaultEvent(const std::string & errMsg,int32_t ret)659 void SurfaceEncoderAdapter::SetFaultEvent(const std::string &errMsg, int32_t ret)
660 {
661     SetFaultEvent(errMsg + ", ret = " + std::to_string(ret));
662 }
663 
SetFaultEvent(const std::string & errMsg)664 void SurfaceEncoderAdapter::SetFaultEvent(const std::string &errMsg)
665 {
666     VideoCodecFaultInfo videoCodecFaultInfo;
667     videoCodecFaultInfo.appName = bundleName_;
668     videoCodecFaultInfo.instanceId = std::to_string(instanceId_);
669     videoCodecFaultInfo.callerType = "player_framework";
670     videoCodecFaultInfo.videoCodec = codecMimeType_;
671     videoCodecFaultInfo.errMsg = errMsg;
672     FaultVideoCodecEventWrite(videoCodecFaultInfo);
673 }
674 
SetCallingInfo(int32_t appUid,int32_t appPid,const std::string & bundleName,uint64_t instanceId)675 void SurfaceEncoderAdapter::SetCallingInfo(int32_t appUid, int32_t appPid,
676     const std::string &bundleName, uint64_t instanceId)
677 {
678     appUid_ = appUid;
679     appPid_ = appPid;
680     bundleName_ = bundleName;
681     instanceId_ = instanceId;
682 }
683 
OnInputParameterWithAttrAvailable(uint32_t index,std::shared_ptr<Format> & attribute,std::shared_ptr<Format> & parameter)684 void SurfaceEncoderAdapter::OnInputParameterWithAttrAvailable(uint32_t index, std::shared_ptr<Format> &attribute,
685     std::shared_ptr<Format> &parameter)
686 {
687     MediaAVCodec::AVCodecTrace trace("SurfaceEncoderAdapter::OnInputParameterWithAttrAvailable");
688     if (isTransCoderMode) {
689         MEDIA_LOG_D("isTransCoderMode");
690         parameter->PutIntValue(Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, false);
691         codecServer_->QueueInputParameter(index);
692         return;
693     }
694     std::lock_guard<std::mutex> lock(checkFramesMutex_);
695     int64_t currentPts = 0;
696     attribute->GetLongValue(Tag::MEDIA_TIME_STAMP, currentPts);
697     MEDIA_LOG_D("OnInputParameterWithAttrAvailable currentPts " PUBLIC_LOG_D64, currentPts);
698     int64_t checkFramesPauseTime = 0;
699     bool isDroppedFrames = CheckFrames(currentPts, checkFramesPauseTime);
700     {
701         std::lock_guard<std::mutex> mappingLock(mappingPtsMutex_);
702         if (isDroppedFrames) {
703             totalPauseTime_ = totalPauseTime_ + currentPts - lastBufferTime_;
704         } else {
705             int64_t frameDifference = 1000000; // Frame Difference less 1000000 ns
706             if (checkFramesPauseTime + frameDifference < currentPts - lastBufferTime_) {
707                 totalPauseTime_ = totalPauseTime_ + checkFramesPauseTime;
708             }
709             mappingTimeQueue_.push_back({currentPts, currentPts - totalPauseTime_});
710         }
711         lastBufferTime_ = currentPts;
712     }
713     parameter->PutIntValue(Tag::VIDEO_ENCODER_PER_FRAME_DISCARD, isDroppedFrames);
714     codecServer_->QueueInputParameter(index);
715 }
716 
CheckFrames(int64_t currentPts,int64_t & checkFramesPauseTime)717 bool SurfaceEncoderAdapter::CheckFrames(int64_t currentPts, int64_t &checkFramesPauseTime)
718 {
719     if (pauseResumeQueue_.empty()) {
720         return false;
721     }
722     auto stateCode = pauseResumeQueue_[0].second;
723     MEDIA_LOG_D("CheckFrames stateCode: " PUBLIC_LOG_D32
724         " time:" PUBLIC_LOG_D64, static_cast<int32_t>(stateCode), pauseResumeQueue_[0].first);
725     // means not dropped frames when less than pause time
726     if (stateCode == StateCode::PAUSE && currentPts < pauseResumeQueue_[0].first) {
727         return false;
728     }
729     // means dropped frames when less than resume time
730     if (stateCode == StateCode::RESUME && currentPts < pauseResumeQueue_[0].first) {
731         return true;
732     }
733     if (stateCode == StateCode::PAUSE) {
734         checkFramesPauseTime -= (pauseResumeQueue_[0].first - lastBufferTime_);
735     } else {
736         checkFramesPauseTime += (pauseResumeQueue_[0].first - lastBufferTime_);
737     }
738     pauseResumeQueue_.pop_front();
739     return CheckFrames(currentPts, checkFramesPauseTime);
740 }
741 
GetCurrentTime(int64_t & currentTime)742 void SurfaceEncoderAdapter::GetCurrentTime(int64_t &currentTime)
743 {
744     struct timespec timestamp = {0, 0};
745     clock_gettime(CLOCK_MONOTONIC, &timestamp);
746     currentTime = static_cast<int64_t>(timestamp.tv_sec) * SEC_TO_NS + static_cast<int64_t>(timestamp.tv_nsec);
747 }
748 
AddStartPts(int64_t currentPts)749 void SurfaceEncoderAdapter::AddStartPts(int64_t currentPts)
750 {
751     // start time
752     if (isStartKeyFramePts_) {
753         keyFramePts_ += std::to_string(currentPts / NS_PER_US) + ",";
754         isStartKeyFramePts_ = false;
755         MEDIA_LOG_I("AddStartPts success %{public}s end", keyFramePts_.c_str());
756     }
757 }
758 
AddStopPts()759 void SurfaceEncoderAdapter::AddStopPts()
760 {
761     // stop time
762     MEDIA_LOG_D("AddStopPts enter");
763     if (isStopKeyFramePts_) {
764         if (currentKeyFramePts_ > stopTime_) {
765             keyFramePts_ += std::to_string(preKeyFramePts_ / NS_PER_US);
766             MEDIA_LOG_I("AddStopPts preKeyFramePts_ %{public}s end", keyFramePts_.c_str());
767         } else {
768             keyFramePts_ += std::to_string(currentKeyFramePts_ / NS_PER_US);
769             MEDIA_LOG_I("AddStopPts currentKeyFramePts_ %{public}s end", keyFramePts_.c_str());
770         }
771         isStopKeyFramePts_ = false;
772         encoderAdapterKeyFramePtsCallback_->OnReportKeyFramePts(keyFramePts_);
773         keyFramePts_.clear();
774     }
775 }
776 
AddPauseResumePts(int64_t currentPts)777 bool SurfaceEncoderAdapter::AddPauseResumePts(int64_t currentPts)
778 {
779     if (pauseResumePts_.empty()) {
780         return false;
781     }
782     auto stateCode = pauseResumePts_[0].second;
783     MEDIA_LOG_D("CheckFrames stateCode: " PUBLIC_LOG_D32
784         " time:" PUBLIC_LOG_D64, static_cast<int32_t>(stateCode), pauseResumePts_[0].first);
785     // means not dropped frames when less than pause time
786     if (stateCode == StateCode::PAUSE && currentPts < pauseResumePts_[0].first) {
787         return false;
788     }
789     // means dropped frames when less than resume time
790     if (stateCode == StateCode::RESUME && currentPts < pauseResumePts_[0].first) {
791         return true;
792     }
793     if (stateCode == StateCode::PAUSE) {
794         MEDIA_LOG_D("AddPausePts %{public}s start", keyFramePts_.c_str());
795         keyFramePts_ += std::to_string(preKeyFramePts_ / NS_PER_US) + ",";
796         MEDIA_LOG_D("AddPausePts %{public}s end", keyFramePts_.c_str());
797     }
798     if (stateCode == StateCode::RESUME) {
799         MEDIA_LOG_D("AddResumePts %{public}s start", keyFramePts_.c_str());
800         keyFramePts_ += std::to_string(currentKeyFramePts_ / NS_PER_US) + ",";
801         MEDIA_LOG_D("AddResumePts %{public}s end", keyFramePts_.c_str());
802     }
803     pauseResumePts_.pop_front();
804     return AddPauseResumePts(currentPts);
805 }
806 } // namespace MEDIA
807 } // namespace OHOS