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> ¶meter)
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> ¶meter)
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 ¤tTime)
743 {
744 struct timespec timestamp = {0, 0};
745 clock_gettime(CLOCK_MONOTONIC, ×tamp);
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