1 /*
2 * Copyright (c) 2022 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 "decode_data_process.h"
17
18 #include "distributed_hardware_log.h"
19 #include "graphic_common_c.h"
20
21 #include "dcamera_hisysevent_adapter.h"
22 #include "dcamera_utils_tools.h"
23 #include "decode_surface_listener.h"
24 #include "decode_video_callback.h"
25
26 namespace OHOS {
27 namespace DistributedHardware {
28 const string ENUM_VIDEOFORMAT_STRINGS[] = {
29 "YUVI420", "NV12", "NV21", "RGBA_8888"
30 };
31
~DecodeDataProcess()32 DecodeDataProcess::~DecodeDataProcess()
33 {
34 if (isDecoderProcess_.load()) {
35 DHLOGD("~DecodeDataProcess : ReleaseProcessNode.");
36 ReleaseProcessNode();
37 }
38 }
39
InitNode(const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig,VideoConfigParams & processedConfig)40 int32_t DecodeDataProcess::InitNode(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig,
41 VideoConfigParams& processedConfig)
42 {
43 DHLOGD("Common Init DCamera DecodeNode start.");
44 if (!(IsInDecoderRange(sourceConfig) && IsInDecoderRange(targetConfig))) {
45 DHLOGE("Common Source config or target config are invalid.");
46 return DCAMERA_BAD_VALUE;
47 }
48 if (!IsConvertible(sourceConfig, targetConfig)) {
49 DHLOGE("Common The DecodeNode can't convert %d to %d.", sourceConfig_.GetVideoCodecType(),
50 targetConfig_.GetVideoCodecType());
51 return DCAMERA_BAD_TYPE;
52 }
53
54 sourceConfig_ = sourceConfig;
55 targetConfig_ = targetConfig;
56 if (sourceConfig_.GetVideoCodecType() == targetConfig_.GetVideoCodecType()) {
57 DHLOGD("Disable DecodeNode. The target video codec type %d is the same as the source video codec type %d.",
58 sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType());
59 processedConfig_ = sourceConfig;
60 processedConfig = processedConfig_;
61 isDecoderProcess_.store(true);
62 return DCAMERA_OK;
63 }
64
65 InitCodecEvent();
66 int32_t err = InitDecoder();
67 if (err != DCAMERA_OK) {
68 DHLOGE("Common Init video decoder fail.");
69 ReleaseProcessNode();
70 return err;
71 }
72 alignedHeight_ = GetAlignedHeight(sourceConfig_.GetHeight());
73 processedConfig = processedConfig_;
74 isDecoderProcess_.store(true);
75 return DCAMERA_OK;
76 }
77
IsInDecoderRange(const VideoConfigParams & curConfig)78 bool DecodeDataProcess::IsInDecoderRange(const VideoConfigParams& curConfig)
79 {
80 return (curConfig.GetWidth() >= MIN_VIDEO_WIDTH || curConfig.GetWidth() <= MAX_VIDEO_WIDTH ||
81 curConfig.GetHeight() >= MIN_VIDEO_HEIGHT || curConfig.GetHeight() <= MAX_VIDEO_HEIGHT ||
82 curConfig.GetFrameRate() >= MIN_FRAME_RATE || curConfig.GetFrameRate() <= MAX_FRAME_RATE);
83 }
84
IsConvertible(const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig)85 bool DecodeDataProcess::IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig)
86 {
87 return (sourceConfig.GetVideoCodecType() == targetConfig.GetVideoCodecType() ||
88 targetConfig.GetVideoCodecType() == VideoCodecType::NO_CODEC);
89 }
90
InitCodecEvent()91 void DecodeDataProcess::InitCodecEvent()
92 {
93 DHLOGD("Common Init DecodeNode eventBus, and add handler for it.");
94 eventBusDecode_ = std::make_shared<EventBus>("DeDtProcHandler");
95 DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
96 eventBusRegHandleDecode_ = eventBusDecode_->AddHandler<DCameraCodecEvent>(codecEvent.GetType(), *this);
97
98 DHLOGD("Common Add handler for DCamera pipeline eventBus.");
99 eventBusRegHandlePipeline2Decode_ = eventBusPipeline_->AddHandler<DCameraCodecEvent>(codecEvent.GetType(), *this);
100 }
101
InitDecoder()102 int32_t DecodeDataProcess::InitDecoder()
103 {
104 DHLOGD("Init video decoder.");
105 int32_t ret = ConfigureVideoDecoder();
106 if (ret != DCAMERA_OK) {
107 DHLOGE("Init video decoder metadata format failed.");
108 return ret;
109 }
110
111 ret = StartVideoDecoder();
112 if (ret != DCAMERA_OK) {
113 DHLOGE("Start Video decoder failed.");
114 ReportDcamerOptFail(DCAMERA_OPT_FAIL, DCAMERA_DECODE_ERROR,
115 CreateMsg("start video decoder failed, width: %d, height: %d, format: %s", sourceConfig_.GetWidth(),
116 sourceConfig_.GetHeight(),
117 ENUM_VIDEOFORMAT_STRINGS[static_cast<int32_t>(sourceConfig_.GetVideoformat())].c_str()));
118 return ret;
119 }
120 return DCAMERA_OK;
121 }
122
ConfigureVideoDecoder()123 int32_t DecodeDataProcess::ConfigureVideoDecoder()
124 {
125 int32_t ret = InitDecoderMetadataFormat();
126 if (ret != DCAMERA_OK) {
127 DHLOGE("Init video decoder metadata format failed. Error code %d.", ret);
128 return ret;
129 }
130
131 videoDecoder_ = Media::VideoDecoderFactory::CreateByMime(processType_);
132 if (videoDecoder_ == nullptr) {
133 DHLOGE("Create video decoder failed.");
134 return DCAMERA_INIT_ERR;
135 }
136 decodeVideoCallback_ = std::make_shared<DecodeVideoCallback>(shared_from_this());
137 ret = videoDecoder_->SetCallback(decodeVideoCallback_);
138 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
139 DHLOGE("Set video decoder callback failed. Error code %d.", ret);
140 return DCAMERA_INIT_ERR;
141 }
142
143 ret = videoDecoder_->Configure(metadataFormat_);
144 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
145 DHLOGE("Set video decoder metadata format failed. Error code %d.", ret);
146 return DCAMERA_INIT_ERR;
147 }
148
149 ret = SetDecoderOutputSurface();
150 if (ret != DCAMERA_OK) {
151 DHLOGE("Set decoder output surface failed. Error code %d.", ret);
152 return ret;
153 }
154
155 return DCAMERA_OK;
156 }
157
InitDecoderMetadataFormat()158 int32_t DecodeDataProcess::InitDecoderMetadataFormat()
159 {
160 DHLOGD("Common Init video decoder metadata format.");
161 processType_ = "video/mp4v-es";
162 metadataFormat_.PutStringValue("codec_mime", processType_);
163
164 metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::RGBA);
165 metadataFormat_.PutIntValue("max_input_size", MAX_RGB32_BUFFER_SIZE);
166 metadataFormat_.PutIntValue("width", sourceConfig_.GetWidth());
167 metadataFormat_.PutIntValue("height", sourceConfig_.GetHeight());
168 metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE);
169
170 processedConfig_ = sourceConfig_;
171 processedConfig_.SetVideoCodecType(VideoCodecType::NO_CODEC);
172 return DCAMERA_OK;
173 }
174
SetDecoderOutputSurface()175 int32_t DecodeDataProcess::SetDecoderOutputSurface()
176 {
177 DHLOGD("Set the video decoder output surface.");
178 if (videoDecoder_ == nullptr) {
179 DHLOGE("The video decoder is null.");
180 return DCAMERA_BAD_VALUE;
181 }
182
183 decodeConsumerSurface_ = Surface::CreateSurfaceAsConsumer();
184 if (decodeConsumerSurface_ == nullptr) {
185 DHLOGE("Creat the decode consumer surface fail.");
186 return DCAMERA_INIT_ERR;
187 }
188 decodeConsumerSurface_->SetDefaultWidthAndHeight((int32_t)sourceConfig_.GetWidth(),
189 (int32_t)sourceConfig_.GetHeight());
190 decodeSurfaceListener_ = new DecodeSurfaceListener(decodeConsumerSurface_, shared_from_this());
191 if (decodeConsumerSurface_->RegisterConsumerListener(decodeSurfaceListener_) !=
192 SURFACE_ERROR_OK) {
193 DHLOGE("Register consumer listener fail.");
194 return DCAMERA_INIT_ERR;
195 }
196
197 sptr<IBufferProducer> surfaceProducer = decodeConsumerSurface_->GetProducer();
198 if (surfaceProducer == nullptr) {
199 DHLOGE("Get the surface producer of the decode consumer surface fail.");
200 return DCAMERA_INIT_ERR;
201 }
202 decodeProducerSurface_ = Surface::CreateSurfaceAsProducer(surfaceProducer);
203 if (decodeProducerSurface_ == nullptr) {
204 DHLOGE("Creat the decode producer surface of the decode consumer surface fail.");
205 return DCAMERA_INIT_ERR;
206 }
207
208 DHLOGD("Set the producer surface to video decoder output surface.");
209 int32_t err = videoDecoder_->SetOutputSurface(decodeProducerSurface_);
210 if (err != Media::MediaServiceErrCode::MSERR_OK) {
211 DHLOGE("Set decoder output surface fail.");
212 return DCAMERA_INIT_ERR;
213 }
214 return DCAMERA_OK;
215 }
216
StartVideoDecoder()217 int32_t DecodeDataProcess::StartVideoDecoder()
218 {
219 if (videoDecoder_ == nullptr) {
220 DHLOGE("The video decoder does not exist before StartVideoDecoder.");
221 return DCAMERA_BAD_VALUE;
222 }
223
224 int32_t ret = videoDecoder_->Prepare();
225 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
226 DHLOGE("Video decoder prepare failed. Error code %d.", ret);
227 return DCAMERA_INIT_ERR;
228 }
229 ret = videoDecoder_->Start();
230 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
231 DHLOGE("Video decoder start failed. Error code %d.", ret);
232 return DCAMERA_INIT_ERR;
233 }
234 return DCAMERA_OK;
235 }
236
237
StopVideoDecoder()238 int32_t DecodeDataProcess::StopVideoDecoder()
239 {
240 if (videoDecoder_ == nullptr) {
241 DHLOGE("The video decoder does not exist before StopVideoDecoder.");
242 return DCAMERA_BAD_VALUE;
243 }
244
245 bool isSuccess = true;
246 int32_t ret = videoDecoder_->Flush();
247 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
248 DHLOGE("VideoDecoder flush failed. Error type: %d.", ret);
249 isSuccess = isSuccess && false;
250 }
251 ret = videoDecoder_->Stop();
252 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
253 DHLOGE("VideoDecoder stop failed. Error type: %d.", ret);
254 isSuccess = isSuccess && false;
255 }
256 if (!isSuccess) {
257 return DCAMERA_BAD_OPERATE;
258 }
259 return DCAMERA_OK;
260 }
261
ReleaseVideoDecoder()262 void DecodeDataProcess::ReleaseVideoDecoder()
263 {
264 std::lock_guard<std::mutex> lck(mtxDecoderState_);
265 DHLOGD("Start release videoDecoder.");
266 if (videoDecoder_ == nullptr) {
267 DHLOGE("The video decoder does not exist before ReleaseVideoDecoder.");
268 decodeVideoCallback_ = nullptr;
269 return;
270 }
271 int32_t ret = StopVideoDecoder();
272 if (ret != DCAMERA_OK) {
273 DHLOGE("StopVideoDecoder failed.");
274 }
275 ret = videoDecoder_->Release();
276 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
277 DHLOGE("VideoDecoder release failed. Error type: %d.", ret);
278 }
279 videoDecoder_ = nullptr;
280 decodeVideoCallback_ = nullptr;
281 }
282
ReleaseDecoderSurface()283 void DecodeDataProcess::ReleaseDecoderSurface()
284 {
285 if (decodeConsumerSurface_ == nullptr) {
286 decodeProducerSurface_ = nullptr;
287 DHLOGE("The decode consumer surface does not exist before UnregisterConsumerListener.");
288 return;
289 }
290 int32_t ret = decodeConsumerSurface_->UnregisterConsumerListener();
291 if (ret != SURFACE_ERROR_OK) {
292 DHLOGE("Unregister consumer listener failed. Error type: %d.", ret);
293 }
294 decodeConsumerSurface_ = nullptr;
295 decodeProducerSurface_ = nullptr;
296 }
297
ReleaseCodecEvent()298 void DecodeDataProcess::ReleaseCodecEvent()
299 {
300 DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
301 if (eventBusDecode_ != nullptr) {
302 eventBusDecode_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandleDecode_);
303 eventBusRegHandleDecode_ = nullptr;
304 eventBusDecode_ = nullptr;
305 }
306 if (eventBusPipeline_ != nullptr) {
307 eventBusPipeline_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_);
308 eventBusRegHandlePipeline2Decode_ = nullptr;
309 eventBusPipeline_ = nullptr;
310 }
311 DHLOGD("Release DecodeNode eventBusDecode and eventBusPipeline end.");
312 }
313
ReleaseProcessNode()314 void DecodeDataProcess::ReleaseProcessNode()
315 {
316 DHLOGD("Start release [%d] node : DecodeNode.", nodeRank_);
317 isDecoderProcess_.store(false);
318 ReleaseVideoDecoder();
319 ReleaseDecoderSurface();
320 ReleaseCodecEvent();
321
322 processType_ = "";
323 std::queue<std::shared_ptr<DataBuffer>>().swap(inputBuffersQueue_);
324 std::queue<uint32_t>().swap(availableInputIndexsQueue_);
325 waitDecoderOutputCount_ = 0;
326 lastFeedDecoderInputBufferTimeUs_ = 0;
327 outputTimeStampUs_ = 0;
328 alignedHeight_ = 0;
329
330 if (nextDataProcess_ != nullptr) {
331 nextDataProcess_->ReleaseProcessNode();
332 nextDataProcess_ = nullptr;
333 }
334 DHLOGD("Release [%d] node : DecodeNode end.", nodeRank_);
335 }
336
ProcessData(std::vector<std::shared_ptr<DataBuffer>> & inputBuffers)337 int32_t DecodeDataProcess::ProcessData(std::vector<std::shared_ptr<DataBuffer>>& inputBuffers)
338 {
339 DHLOGD("Process data in DecodeDataProcess.");
340 if (inputBuffers.empty()) {
341 DHLOGE("The input data buffers is empty.");
342 return DCAMERA_BAD_VALUE;
343 }
344 if (sourceConfig_.GetVideoCodecType() == processedConfig_.GetVideoCodecType()) {
345 DHLOGD("The target VideoCodecType : %d is the same as the source VideoCodecType : %d.",
346 sourceConfig_.GetVideoCodecType(), processedConfig_.GetVideoCodecType());
347 return DecodeDone(inputBuffers);
348 }
349
350 if (videoDecoder_ == nullptr) {
351 DHLOGE("The video decoder does not exist before decoding data.");
352 return DCAMERA_INIT_ERR;
353 }
354 if (inputBuffersQueue_.size() > VIDEO_DECODER_QUEUE_MAX) {
355 DHLOGE("video decoder input buffers queue over flow.");
356 return DCAMERA_INDEX_OVERFLOW;
357 }
358 if (inputBuffers[0]->Size() > MAX_RGB32_BUFFER_SIZE) {
359 DHLOGE("DecodeNode input buffer size %d error.", inputBuffers[0]->Size());
360 return DCAMERA_MEMORY_OPT_ERROR;
361 }
362 if (!isDecoderProcess_.load()) {
363 DHLOGE("Decoder node occurred error or start release.");
364 return DCAMERA_DISABLE_PROCESS;
365 }
366 inputBuffersQueue_.push(inputBuffers[0]);
367 DHLOGD("Push inputBuffer sucess. BufSize %d, QueueSize %d.", inputBuffers[0]->Size(), inputBuffersQueue_.size());
368 int32_t err = FeedDecoderInputBuffer();
369 if (err != DCAMERA_OK) {
370 int32_t sleepTimeUs = 5000;
371 std::this_thread::sleep_for(std::chrono::microseconds(sleepTimeUs));
372 DHLOGD("Feed decoder input buffer fail. Try FeedDecoderInputBuffer again.");
373 std::shared_ptr<CodecPacket> reFeedInputPacket = std::make_shared<CodecPacket>();
374 reFeedInputPacket->SetVideoCodecType(sourceConfig_.GetVideoCodecType());
375 DCameraCodecEvent dCamCodecEv(*this, reFeedInputPacket, VideoCodecAction::ACTION_ONCE_AGAIN);
376 if (eventBusPipeline_ == nullptr) {
377 DHLOGE("eventBusPipeline_ is nullptr.");
378 return DCAMERA_BAD_VALUE;
379 }
380 eventBusPipeline_->PostEvent<DCameraCodecEvent>(dCamCodecEv, POSTMODE::POST_ASYNC);
381 }
382 return DCAMERA_OK;
383 }
384
FeedDecoderInputBuffer()385 int32_t DecodeDataProcess::FeedDecoderInputBuffer()
386 {
387 DHLOGD("Feed decoder input buffer.");
388 while ((!inputBuffersQueue_.empty()) && (isDecoderProcess_.load())) {
389 std::shared_ptr<DataBuffer> buffer = inputBuffersQueue_.front();
390 if (buffer == nullptr || availableInputIndexsQueue_.empty()) {
391 DHLOGE("inputBuffersQueue size %d, availableInputIndexsQueue size %d.",
392 inputBuffersQueue_.size(), availableInputIndexsQueue_.size());
393 return DCAMERA_BAD_VALUE;
394 }
395
396 {
397 std::lock_guard<std::mutex> lck(mtxDecoderState_);
398 if (videoDecoder_ == nullptr) {
399 DHLOGE("The video decoder does not exist before GetInputBuffer.");
400 return DCAMERA_OK;
401 }
402 uint32_t index = availableInputIndexsQueue_.front();
403 std::shared_ptr<Media::AVSharedMemory> sharedMemoryInput = videoDecoder_->GetInputBuffer(index);
404 if (sharedMemoryInput == nullptr) {
405 DHLOGE("Failed to obtain the input shared memory corresponding to the [%d] index.", index);
406 return DCAMERA_BAD_VALUE;
407 }
408 size_t inputMemoDataSize = static_cast<size_t>(sharedMemoryInput->GetSize());
409 errno_t err = memcpy_s(sharedMemoryInput->GetBase(), inputMemoDataSize, buffer->Data(), buffer->Size());
410 if (err != EOK) {
411 DHLOGE("memcpy_s buffer failed.");
412 return DCAMERA_MEMORY_OPT_ERROR;
413 }
414 int64_t timeUs = GetDecoderTimeStamp();
415 DHLOGD("Decoder input buffer size %d, timeStamp %lld.", buffer->Size(), (long long)timeUs);
416 Media::AVCodecBufferInfo bufferInfo {timeUs, static_cast<int32_t>(buffer->Size()), 0};
417 int32_t ret = videoDecoder_->QueueInputBuffer(index, bufferInfo,
418 Media::AVCODEC_BUFFER_FLAG_NONE);
419 if (ret != Media::MediaServiceErrCode::MSERR_OK) {
420 DHLOGE("queue Input buffer failed.");
421 return DCAMERA_BAD_OPERATE;
422 }
423 }
424
425 inputBuffersQueue_.pop();
426 DHLOGD("Push inputBuffer sucess. inputBuffersQueue size is %d.", inputBuffersQueue_.size());
427
428 IncreaseWaitDecodeCnt();
429 }
430 return DCAMERA_OK;
431 }
432
GetDecoderTimeStamp()433 int64_t DecodeDataProcess::GetDecoderTimeStamp()
434 {
435 int64_t TimeIntervalStampUs = 0;
436 int64_t nowTimeUs = GetNowTimeStampUs();
437 if (lastFeedDecoderInputBufferTimeUs_ == 0) {
438 lastFeedDecoderInputBufferTimeUs_ = nowTimeUs;
439 return TimeIntervalStampUs;
440 }
441 TimeIntervalStampUs = nowTimeUs - lastFeedDecoderInputBufferTimeUs_;
442 lastFeedDecoderInputBufferTimeUs_ = nowTimeUs;
443 return TimeIntervalStampUs;
444 }
445
IncreaseWaitDecodeCnt()446 void DecodeDataProcess::IncreaseWaitDecodeCnt()
447 {
448 std::lock_guard<std::mutex> lck(mtxHoldCount_);
449 availableInputIndexsQueue_.pop();
450 waitDecoderOutputCount_++;
451 DHLOGD("Wait decoder output frames number is %d.", waitDecoderOutputCount_);
452 }
453
ReduceWaitDecodeCnt()454 void DecodeDataProcess::ReduceWaitDecodeCnt()
455 {
456 std::lock_guard<std::mutex> lck(mtxHoldCount_);
457 if (waitDecoderOutputCount_ <= 0) {
458 DHLOGE("The waitDecoderOutputCount_ = %d.", waitDecoderOutputCount_);
459 }
460 if (outputTimeStampUs_ == 0) {
461 waitDecoderOutputCount_ -= FIRST_FRAME_INPUT_NUM;
462 } else {
463 waitDecoderOutputCount_--;
464 }
465 DHLOGD("Wait decoder output frames number is %d.", waitDecoderOutputCount_);
466 }
467
GetDecoderOutputBuffer(const sptr<Surface> & surface)468 void DecodeDataProcess::GetDecoderOutputBuffer(const sptr<Surface>& surface)
469 {
470 DHLOGD("Get decoder output buffer.");
471 if (surface == nullptr) {
472 DHLOGE("Get decode consumer surface failed.");
473 return;
474 }
475 Rect damage = {0, 0, 0, 0};
476 int32_t acquireFence = 0;
477 int64_t timeStampUs = 0;
478 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
479 GSError ret = surface->AcquireBuffer(surfaceBuffer, acquireFence, timeStampUs, damage);
480 if (ret != GSERROR_OK || surfaceBuffer == nullptr) {
481 DHLOGE("Acquire surface buffer failed!");
482 return;
483 }
484 int32_t alignedWidth = surfaceBuffer->GetStride();
485 if (surfaceBuffer->GetSize() > BUFFER_MAX_SIZE || alignedWidth > ALIGNED_WIDTH_MAX_SIZE) {
486 DHLOGE("surface buffer size or alignedWidth too long");
487 return;
488 }
489 int32_t alignedHeight = alignedHeight_;
490 DHLOGD("OutputBuffer alignedWidth %d, alignedHeight %d, TimeUs %lld.", alignedWidth, alignedHeight, timeStampUs);
491 CopyDecodedImage(surfaceBuffer, timeStampUs, alignedWidth, alignedHeight);
492 surface->ReleaseBuffer(surfaceBuffer, -1);
493 outputTimeStampUs_ = timeStampUs;
494 ReduceWaitDecodeCnt();
495 }
496
CopyDecodedImage(const sptr<SurfaceBuffer> & surBuf,int64_t timeStampUs,int32_t alignedWidth,int32_t alignedHeight)497 void DecodeDataProcess::CopyDecodedImage(const sptr<SurfaceBuffer>& surBuf, int64_t timeStampUs, int32_t alignedWidth,
498 int32_t alignedHeight)
499 {
500 if (!IsCorrectSurfaceBuffer(surBuf, alignedWidth, alignedHeight)) {
501 DHLOGE("Surface output buffer error.");
502 return;
503 }
504
505 size_t rgbImageSize = static_cast<size_t>(sourceConfig_.GetWidth() * sourceConfig_.GetHeight() *
506 RGB32_MEMORY_COEFFICIENT);
507 std::shared_ptr<DataBuffer> bufferOutput = std::make_shared<DataBuffer>(rgbImageSize);
508 uint8_t *addr = static_cast<uint8_t *>(surBuf->GetVirAddr());
509 errno_t err = memcpy_s(bufferOutput->Data(), bufferOutput->Size(), addr, rgbImageSize);
510 if (err != EOK) {
511 DHLOGE("memcpy_s surface buffer failed.");
512 return;
513 }
514 bufferOutput->SetInt64("timeUs", timeStampUs);
515 bufferOutput->SetInt32("Videoformat", static_cast<int32_t>(processedConfig_.GetVideoformat()));
516 bufferOutput->SetInt32("alignedWidth", processedConfig_.GetWidth());
517 bufferOutput->SetInt32("alignedHeight", processedConfig_.GetHeight());
518 bufferOutput->SetInt32("width", processedConfig_.GetWidth());
519 bufferOutput->SetInt32("height", processedConfig_.GetHeight());
520 PostOutputDataBuffers(bufferOutput);
521 }
522
IsCorrectSurfaceBuffer(const sptr<SurfaceBuffer> & surBuf,int32_t alignedWidth,int32_t alignedHeight)523 bool DecodeDataProcess::IsCorrectSurfaceBuffer(const sptr<SurfaceBuffer>& surBuf, int32_t alignedWidth,
524 int32_t alignedHeight)
525 {
526 if (surBuf == nullptr) {
527 DHLOGE("surface buffer is null!");
528 return false;
529 }
530
531 size_t rgbImageSize = static_cast<size_t>(sourceConfig_.GetWidth() * sourceConfig_.GetHeight() *
532 RGB32_MEMORY_COEFFICIENT);
533 size_t surfaceBufSize = static_cast<size_t>(surBuf->GetSize());
534 if (rgbImageSize > surfaceBufSize) {
535 DHLOGE("Buffer size error, rgbImageSize %d, surBufSize %d.", rgbImageSize, surBuf->GetSize());
536 return false;
537 }
538 return true;
539 }
540
PostOutputDataBuffers(std::shared_ptr<DataBuffer> & outputBuffer)541 void DecodeDataProcess::PostOutputDataBuffers(std::shared_ptr<DataBuffer>& outputBuffer)
542 {
543 if (eventBusDecode_ == nullptr || outputBuffer == nullptr) {
544 DHLOGE("eventBusDecode_ or outputBuffer is null.");
545 return;
546 }
547 std::vector<std::shared_ptr<DataBuffer>> multiDataBuffers;
548 multiDataBuffers.push_back(outputBuffer);
549 std::shared_ptr<CodecPacket> transNextNodePacket = std::make_shared<CodecPacket>(VideoCodecType::NO_CODEC,
550 multiDataBuffers);
551 DCameraCodecEvent dCamCodecEv(*this, transNextNodePacket, VideoCodecAction::NO_ACTION);
552 eventBusDecode_->PostEvent<DCameraCodecEvent>(dCamCodecEv, POSTMODE::POST_ASYNC);
553 DHLOGD("Send video decoder output asynchronous DCameraCodecEvents success.");
554 }
555
DecodeDone(std::vector<std::shared_ptr<DataBuffer>> & outputBuffers)556 int32_t DecodeDataProcess::DecodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
557 {
558 DHLOGD("Decoder Done.");
559 if (outputBuffers.empty()) {
560 DHLOGE("The received data buffers is empty.");
561 return DCAMERA_BAD_VALUE;
562 }
563
564 if (nextDataProcess_ != nullptr) {
565 DHLOGD("Send to the next node of the decoder for processing.");
566 int32_t err = nextDataProcess_->ProcessData(outputBuffers);
567 if (err != DCAMERA_OK) {
568 DHLOGE("Someone node after the decoder processes fail.");
569 }
570 return err;
571 }
572 DHLOGD("The current node is the last node, and Output the processed video buffer");
573 std::shared_ptr<DCameraPipelineSource> targetPipelineSource = callbackPipelineSource_.lock();
574 if (targetPipelineSource == nullptr) {
575 DHLOGE("callbackPipelineSource_ is nullptr.");
576 return DCAMERA_BAD_VALUE;
577 }
578 targetPipelineSource->OnProcessedVideoBuffer(outputBuffers[0]);
579 return DCAMERA_OK;
580 }
581
OnEvent(DCameraCodecEvent & ev)582 void DecodeDataProcess::OnEvent(DCameraCodecEvent& ev)
583 {
584 DHLOGD("Receiving asynchronous DCameraCodecEvents.");
585 std::shared_ptr<CodecPacket> receivedCodecPacket = ev.GetCodecPacket();
586 VideoCodecAction action = ev.GetAction();
587 switch (action) {
588 case VideoCodecAction::NO_ACTION: {
589 if (receivedCodecPacket == nullptr) {
590 DHLOGE("the received codecPacket of action [%d] is null.", action);
591 OnError();
592 return;
593 }
594 std::vector<std::shared_ptr<DataBuffer>> rgbDataBuffers = receivedCodecPacket->GetDataBuffers();
595 DecodeDone(rgbDataBuffers);
596 break;
597 }
598 case VideoCodecAction::ACTION_ONCE_AGAIN:
599 DHLOGD("Try FeedDecoderInputBuffer again.");
600 FeedDecoderInputBuffer();
601 return;
602 default:
603 DHLOGD("The action : %d is not supported.", action);
604 return;
605 }
606 }
607
OnError()608 void DecodeDataProcess::OnError()
609 {
610 DHLOGD("DecodeDataProcess : OnError.");
611 isDecoderProcess_.store(false);
612 if (videoDecoder_ != nullptr) {
613 videoDecoder_->Stop();
614 }
615 std::shared_ptr<DCameraPipelineSource> targetPipelineSource = callbackPipelineSource_.lock();
616 if (targetPipelineSource == nullptr) {
617 DHLOGE("callbackPipelineSource_ is nullptr.");
618 return;
619 }
620 targetPipelineSource->OnError(DataProcessErrorType::ERROR_PIPELINE_DECODER);
621 }
622
OnInputBufferAvailable(uint32_t index)623 void DecodeDataProcess::OnInputBufferAvailable(uint32_t index)
624 {
625 DHLOGD("DecodeDataProcess::OnInputBufferAvailable");
626 std::lock_guard<std::mutex> lck(mtxHoldCount_);
627 if (availableInputIndexsQueue_.size() > VIDEO_DECODER_QUEUE_MAX) {
628 DHLOGE("Video decoder available indexs queue overflow.");
629 return;
630 }
631 DHLOGD("Video decoder available indexs queue push index [%d].", index);
632 availableInputIndexsQueue_.push(index);
633 }
634
OnOutputFormatChanged(const Media::Format & format)635 void DecodeDataProcess::OnOutputFormatChanged(const Media::Format &format)
636 {
637 if (decodeOutputFormat_.GetFormatMap().empty()) {
638 DHLOGE("The first changed video decoder output format is null.");
639 return;
640 }
641 decodeOutputFormat_ = format;
642 }
643
OnOutputBufferAvailable(uint32_t index,const Media::AVCodecBufferInfo & info,const Media::AVCodecBufferFlag & flag)644 void DecodeDataProcess::OnOutputBufferAvailable(uint32_t index, const Media::AVCodecBufferInfo& info,
645 const Media::AVCodecBufferFlag& flag)
646 {
647 if (!isDecoderProcess_.load()) {
648 DHLOGE("Decoder node occurred error or start release.");
649 return;
650 }
651 DHLOGD("Video decode buffer info: presentation TimeUs %lld, size %d, offset %d, flag %d",
652 info.presentationTimeUs, info.size, info.offset, flag);
653 outputInfo_ = info;
654 {
655 std::lock_guard<std::mutex> lck(mtxDecoderState_);
656 if (videoDecoder_ == nullptr) {
657 DHLOGE("The video decoder does not exist before decoding data.");
658 return;
659 }
660 int32_t errRelease = videoDecoder_->ReleaseOutputBuffer(index, true);
661 if (errRelease != Media::MediaServiceErrCode::MSERR_OK) {
662 DHLOGE("The video decoder output decoded data to surface fail, index : [%d].", index);
663 }
664 }
665 }
666
GetSourceConfig() const667 VideoConfigParams DecodeDataProcess::GetSourceConfig() const
668 {
669 return sourceConfig_;
670 }
671
GetTargetConfig() const672 VideoConfigParams DecodeDataProcess::GetTargetConfig() const
673 {
674 return targetConfig_;
675 }
676 } // namespace DistributedHardware
677 } // namespace OHOS
678