1 /*
2 * Copyright (c) 2022-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 "image_sink_decoder.h"
17
18 #include <chrono>
19 #include <pthread.h>
20 #include <securec.h>
21
22 #include "dscreen_constants.h"
23 #include "dscreen_errcode.h"
24 #include "dscreen_hisysevent.h"
25 #include "dscreen_log.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 constexpr const char* DECODE_THREAD = "DecodeThread";
ConfigureDecoder(const VideoParam & configParam)30 int32_t ImageSinkDecoder::ConfigureDecoder(const VideoParam &configParam)
31 {
32 DHLOGI("%s: ConfigureDecoder.", LOG_TAG);
33 int32_t ret = InitVideoDecoder(configParam);
34 if (ret != DH_SUCCESS) {
35 DHLOGE("%s: InitVideoDecoder failed.", LOG_TAG);
36 return ret;
37 }
38
39 ret = SetDecoderFormat(configParam);
40 if (ret != DH_SUCCESS) {
41 DHLOGE("%s: SetDecoderFormat failed.", LOG_TAG);
42 return ret;
43 }
44 configParam_ = configParam;
45 ret = AddSurface();
46 if (ret != DH_SUCCESS) {
47 DHLOGE("%s: Add surface failed ret: %." PRId32, LOG_TAG, ret);
48 consumerSurface_ = nullptr;
49 producerSurface_ = nullptr;
50 return ret;
51 }
52 alignedHeight_ = configParam_.GetVideoHeight();
53 if (alignedHeight_ % ALIGNEDBITS != 0) {
54 alignedHeight_ = ((alignedHeight_ / ALIGNEDBITS) + 1) * ALIGNEDBITS;
55 }
56 return DH_SUCCESS;
57 }
58
AddSurface()59 int32_t ImageSinkDecoder::AddSurface()
60 {
61 DHLOGI("%s: AddSurface.", LOG_TAG);
62 consumerSurface_ = IConsumerSurface::Create();
63 if (consumerSurface_ == nullptr) {
64 DHLOGE("%s: Create consumer surface failed.", LOG_TAG);
65 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
66 }
67
68 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
69 if (producer == nullptr) {
70 DHLOGE("%s: Get preducer surface failed.", LOG_TAG);
71 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
72 }
73
74 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
75 if (producerSurface_ == nullptr) {
76 DHLOGE("%s: Create preducer surface failed.", LOG_TAG);
77 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
78 }
79
80 if (consumerBufferListener_ == nullptr) {
81 consumerBufferListener_ = new ConsumBufferListener(shared_from_this());
82 }
83 consumerSurface_->RegisterConsumerListener(consumerBufferListener_);
84 lastFrameSize_ = static_cast<int32_t>(configParam_.GetVideoWidth() *
85 configParam_.GetVideoHeight() * RGB_CHROMA / TWO);
86 lastFrame_ = new uint8_t[lastFrameSize_];
87 return DH_SUCCESS;
88 }
89
GetLastFrame()90 uint8_t *ImageSinkDecoder::GetLastFrame()
91 {
92 return lastFrame_;
93 }
94
GetWinSurfaceBuffer()95 sptr<SurfaceBuffer> ImageSinkDecoder::GetWinSurfaceBuffer()
96 {
97 DHLOGI("%s: GetWinSurfaceBuffer.", LOG_TAG);
98 sptr<SurfaceBuffer> windowSurfaceBuffer = nullptr;
99 int32_t releaseFence = -1;
100 OHOS::BufferRequestConfig requestConfig = {
101 .width = configParam_.GetVideoWidth(),
102 .height = configParam_.GetVideoHeight(),
103 .strideAlignment = STRIDE_ALIGNMENT,
104 .format = GRAPHIC_PIXEL_FMT_YCBCR_420_SP,
105 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
106 };
107 SurfaceError surfaceErr = windowSurface_->RequestBuffer(windowSurfaceBuffer, releaseFence, requestConfig);
108 if (surfaceErr != SURFACE_ERROR_OK || windowSurfaceBuffer == nullptr) {
109 DHLOGE("%s: windowSurface_ request buffer failed, buffer is nullptr.", LOG_TAG);
110 windowSurface_->CancelBuffer(windowSurfaceBuffer);
111 }
112 return windowSurfaceBuffer;
113 }
114
NormalProcess(sptr<SurfaceBuffer> surfaceBuffer,sptr<SurfaceBuffer> windowSurfaceBuffer)115 void ImageSinkDecoder::NormalProcess(sptr<SurfaceBuffer> surfaceBuffer, sptr<SurfaceBuffer> windowSurfaceBuffer)
116 {
117 DHLOGI("%s: NormalProcess.", LOG_TAG);
118 auto surfaceAddr = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
119 auto windowSurfaceAddr = static_cast<uint8_t*>(windowSurfaceBuffer->GetVirAddr());
120 int32_t sizeData = lastFrameSize_;
121 uint32_t size = windowSurfaceBuffer->GetSize();
122 int32_t ret = memcpy_s(windowSurfaceAddr, size, surfaceAddr, sizeData);
123 if (ret != EOK) {
124 DHLOGE("%s: surfaceBuffer memcpy run failed.", LOG_TAG);
125 windowSurface_->CancelBuffer(windowSurfaceBuffer);
126 }
127 }
128
OffsetProcess(sptr<SurfaceBuffer> surfaceBuffer,sptr<SurfaceBuffer> windowSurfaceBuffer)129 void ImageSinkDecoder::OffsetProcess(sptr<SurfaceBuffer> surfaceBuffer, sptr<SurfaceBuffer> windowSurfaceBuffer)
130 {
131 DHLOGI("%s: OffsetProcess.", LOG_TAG);
132 auto surfaceAddr = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
133 auto windowSurfaceAddr = static_cast<uint8_t*>(windowSurfaceBuffer->GetVirAddr());
134 uint32_t size = windowSurfaceBuffer->GetSize();
135 uint32_t srcDataOffset = 0;
136 uint32_t dstDataOffset = 0;
137 uint32_t alignedWidth = static_cast<uint32_t>(surfaceBuffer->GetStride());
138 uint32_t chromaOffset = configParam_.GetVideoWidth() * configParam_.GetVideoHeight();
139 for (unsigned int yh = 0 ; yh < configParam_.GetVideoHeight() ; yh++) {
140 int32_t ret = memcpy_s(windowSurfaceAddr + dstDataOffset, chromaOffset - dstDataOffset,
141 surfaceAddr + srcDataOffset, configParam_.GetVideoWidth());
142 if (ret != EOK) {
143 DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG);
144 windowSurface_->CancelBuffer(windowSurfaceBuffer);
145 return;
146 }
147 dstDataOffset += configParam_.GetVideoWidth();
148 srcDataOffset += alignedWidth;
149 }
150 dstDataOffset = chromaOffset;
151 srcDataOffset = alignedWidth * alignedHeight_;
152 for (unsigned int uvh = 0 ; uvh < configParam_.GetVideoHeight() / TWO; uvh++) {
153 int32_t ret = memcpy_s(windowSurfaceAddr + dstDataOffset, size - dstDataOffset,
154 surfaceAddr + srcDataOffset, configParam_.GetVideoWidth());
155 if (ret != EOK) {
156 DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG);
157 windowSurface_->CancelBuffer(windowSurfaceBuffer);
158 return;
159 }
160 dstDataOffset += configParam_.GetVideoWidth();
161 srcDataOffset += alignedWidth;
162 }
163 }
164
ConsumeSurface()165 void ImageSinkDecoder::ConsumeSurface()
166 {
167 DHLOGI("%s: ConsumeSurface.", LOG_TAG);
168 std::unique_lock<std::mutex> bufLock(decodeMutex_);
169 if (consumerSurface_ == nullptr) {
170 DHLOGE("%s: consumerSurface_ is nullptr.", LOG_TAG);
171 return;
172 }
173 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
174 int32_t fence = -1;
175 int64_t timestamp = 0;
176 OHOS::Rect damage = {0, 0, 0, 0};
177 SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
178 if (surfaceErr != SURFACE_ERROR_OK) {
179 return;
180 }
181 sptr<OHOS::SurfaceBuffer> windowSurfaceBuffer = GetWinSurfaceBuffer();
182 if (windowSurfaceBuffer == nullptr) {
183 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
184 return;
185 }
186 int32_t alignedWidth = surfaceBuffer->GetStride();
187 if (static_cast<uint32_t>(alignedWidth) == configParam_.GetVideoWidth() &&
188 static_cast<uint32_t>(alignedHeight_) == configParam_.GetVideoHeight()) {
189 NormalProcess(surfaceBuffer, windowSurfaceBuffer);
190 } else {
191 OffsetProcess(surfaceBuffer, windowSurfaceBuffer);
192 }
193 auto windowSurfaceAddr = static_cast<uint8_t*>(windowSurfaceBuffer->GetVirAddr());
194 BufferFlushConfig flushConfig = { {0, 0, windowSurfaceBuffer->GetWidth(), windowSurfaceBuffer->GetHeight()}, 0};
195 int32_t ret = memcpy_s(lastFrame_, lastFrameSize_, windowSurfaceAddr, lastFrameSize_);
196 if (ret != EOK) {
197 DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG);
198 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
199 windowSurface_->CancelBuffer(windowSurfaceBuffer);
200 return;
201 }
202 DHLOGI("%s: ConsumeSurface sucess, send NV12 to window.", LOG_TAG);
203 surfaceErr = windowSurface_->FlushBuffer(windowSurfaceBuffer, -1, flushConfig);
204 if (surfaceErr != SURFACE_ERROR_OK) {
205 DHLOGE("%s: windowSurface_ flush buffer failed.", LOG_TAG);
206 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
207 windowSurface_->CancelBuffer(windowSurfaceBuffer);
208 return;
209 }
210 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
211 }
212
OnBufferAvailable()213 void ConsumBufferListener::OnBufferAvailable()
214 {
215 DHLOGI("%s: OnBufferAvailable, receive NV12 data from decoder.", LOG_TAG);
216 decoder_->ConsumeSurface();
217 }
218
ReleaseDecoder()219 int32_t ImageSinkDecoder::ReleaseDecoder()
220 {
221 DHLOGI("%s: ReleaseDecoder.", LOG_TAG);
222 if (videoDecoder_ == nullptr) {
223 DHLOGE("%s: Decoder is null.", LOG_TAG);
224 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
225 }
226 if (lastFrame_ != nullptr) {
227 delete [] lastFrame_;
228 }
229 int32_t ret = videoDecoder_->Release();
230 if (ret != Media::MSERR_OK) {
231 DHLOGE("%s: ReleaseDecoder failed.", LOG_TAG);
232 return ERR_DH_SCREEN_CODEC_RELEASE_FAILED;
233 }
234 decodeVideoCallback_ = nullptr;
235 videoDecoder_ = nullptr;
236
237 return DH_SUCCESS;
238 }
239
StartDecoder()240 int32_t ImageSinkDecoder::StartDecoder()
241 {
242 DHLOGI("%s: StartDecoder.", LOG_TAG);
243 if (videoDecoder_ == nullptr) {
244 DHLOGE("%s: Decoder is null.", LOG_TAG);
245 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
246 }
247
248 int32_t ret = videoDecoder_->Prepare();
249 if (ret != Media::MSERR_OK) {
250 DHLOGE("%s: Prepare decoder failed.", LOG_TAG);
251 return ERR_DH_SCREEN_CODEC_PREPARE_FAILED;
252 }
253
254 ret = videoDecoder_->Start();
255 if (ret != Media::MSERR_OK) {
256 DHLOGE("%s: Start decoder failed.", LOG_TAG);
257 return ERR_DH_SCREEN_CODEC_START_FAILED;
258 }
259 StartInputThread();
260
261 return DH_SUCCESS;
262 }
263
StopDecoder()264 int32_t ImageSinkDecoder::StopDecoder()
265 {
266 DHLOGI("%s: StopDecoder.", LOG_TAG);
267 if (videoDecoder_ == nullptr) {
268 DHLOGE("%s: Decoder is null.", LOG_TAG);
269 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
270 }
271
272 int32_t ret = videoDecoder_->Flush();
273 if (ret != Media::MSERR_OK) {
274 DHLOGE("%s: Flush decoder failed.", LOG_TAG);
275 return ERR_DH_SCREEN_CODEC_FLUSH_FAILED;
276 }
277
278 ret = videoDecoder_->Stop();
279 if (ret != Media::MSERR_OK) {
280 DHLOGE("%s: Stop decoder failed.", LOG_TAG);
281 return ERR_DH_SCREEN_CODEC_STOP_FAILED;
282 }
283 StopInputThread();
284
285 return DH_SUCCESS;
286 }
287
InitVideoDecoder(const VideoParam & configParam)288 int32_t ImageSinkDecoder::InitVideoDecoder(const VideoParam &configParam)
289 {
290 DHLOGI("%s: InitVideoDecoder.", LOG_TAG);
291 switch (configParam.GetCodecType()) {
292 case VIDEO_CODEC_TYPE_VIDEO_H264:
293 videoDecoder_ = Media::VideoDecoderFactory::CreateByMime("video/avc");
294 break;
295 case VIDEO_CODEC_TYPE_VIDEO_H265:
296 videoDecoder_ = Media::VideoDecoderFactory::CreateByMime("video/hevc");
297 break;
298 case VIDEO_CODEC_TYPE_VIDEO_MPEG4:
299 videoDecoder_ = Media::VideoDecoderFactory::CreateByMime("video/mp4v-es");
300 break;
301 default:
302 DHLOGE("%s: codecType is invalid!", LOG_TAG);
303 videoDecoder_ = nullptr;
304 }
305
306 if (videoDecoder_ == nullptr) {
307 DHLOGE("%s: Create videoEncode failed.", LOG_TAG);
308 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
309 }
310
311 decodeVideoCallback_ = std::make_shared<ImageDecoderCallback>(shared_from_this());
312 int32_t ret = videoDecoder_->SetCallback(decodeVideoCallback_);
313 if (ret != Media::MSERR_OK) {
314 DHLOGE("%s: Set decoder callback failed.", LOG_TAG);
315 return ERR_DH_SCREEN_CODEC_SET_CALLBACK_FAILED;
316 }
317
318 return DH_SUCCESS;
319 }
320
SetDecoderFormat(const VideoParam & configParam)321 int32_t ImageSinkDecoder::SetDecoderFormat(const VideoParam &configParam)
322 {
323 DHLOGI("%s: SetDecoderFormat.", LOG_TAG);
324 if (videoDecoder_ == nullptr) {
325 DHLOGE("%s: Decoder is null.", LOG_TAG);
326 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
327 }
328
329 switch (configParam.GetCodecType()) {
330 case VIDEO_CODEC_TYPE_VIDEO_H264:
331 imageFormat_.PutStringValue("codec_mime", "video/avc");
332 break;
333 case VIDEO_CODEC_TYPE_VIDEO_H265:
334 imageFormat_.PutStringValue("codec_mime", "video/hevc");
335 break;
336 case VIDEO_CODEC_TYPE_VIDEO_MPEG4:
337 imageFormat_.PutStringValue("codec_mime", "video/mp4v-es");
338 break;
339 default:
340 DHLOGE("The current codec type does not support decoding.");
341 return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION;
342 }
343 switch (configParam.GetVideoFormat()) {
344 case VIDEO_DATA_FORMAT_YUVI420:
345 imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::YUVI420);
346 break;
347 case VIDEO_DATA_FORMAT_NV12:
348 imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12);
349 break;
350 case VIDEO_DATA_FORMAT_NV21:
351 imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV21);
352 break;
353 case VIDEO_DATA_FORMAT_RGBA8888:
354 imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::RGBA);
355 break;
356 default:
357 DHLOGE("The current pixel format does not support decoding.");
358 return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION;
359 }
360
361 imageFormat_.PutLongValue("max_input_size", MAX_YUV420_BUFFER_SIZE);
362 imageFormat_.PutIntValue("width", configParam.GetVideoWidth());
363 imageFormat_.PutIntValue("height", configParam.GetVideoHeight());
364 imageFormat_.PutIntValue("frame_rate", configParam.GetFps());
365
366 int32_t ret = videoDecoder_->Configure(imageFormat_);
367 if (ret != Media::MSERR_OK) {
368 DHLOGE("%s: configure decoder format param failed.", LOG_TAG);
369 return ERR_DH_SCREEN_CODEC_CONFIGURE_FAILED;
370 }
371
372 return DH_SUCCESS;
373 }
374
SetOutputSurface(sptr<Surface> & surface)375 int32_t ImageSinkDecoder::SetOutputSurface(sptr<Surface> &surface)
376 {
377 DHLOGI("%s: SetOutputSurface.", LOG_TAG);
378 if (videoDecoder_ == nullptr || surface == nullptr) {
379 DHLOGE("%s: Decoder or surface is null.", LOG_TAG);
380 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
381 }
382 windowSurface_ = surface;
383 if (consumerSurface_ == nullptr || producerSurface_ == nullptr || !configParam_.GetPartialRefreshFlag()) {
384 int32_t ret = videoDecoder_->SetOutputSurface(surface);
385 if (ret != Media::MSERR_OK) {
386 DHLOGE("%s: SetOutputSurface failed.", LOG_TAG);
387 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
388 }
389 } else {
390 int32_t ret = videoDecoder_->SetOutputSurface(producerSurface_);
391 if (ret != Media::MSERR_OK) {
392 DHLOGE("%s: SetOutputSurface failed.", LOG_TAG);
393 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
394 }
395 }
396 return DH_SUCCESS;
397 }
398
InputScreenData(const std::shared_ptr<DataBuffer> & data)399 int32_t ImageSinkDecoder::InputScreenData(const std::shared_ptr<DataBuffer> &data)
400 {
401 if (data == nullptr) {
402 DHLOGE("%s: InputScreenData failed, data is nullptr.", LOG_TAG);
403 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
404 }
405 DHLOGD("%s: InputScreenData.", LOG_TAG);
406 std::lock_guard<std::mutex> dataLock(dataMutex_);
407 while (videoDataQueue_.size() >= DATA_QUEUE_MAX_SIZE) {
408 DHLOGE("%s: videoData queue overflow.", LOG_TAG);
409 videoDataQueue_.pop();
410 }
411 videoDataQueue_.push(data);
412 decodeCond_.notify_all();
413
414 return DH_SUCCESS;
415 }
416
OnError(Media::AVCodecErrorType errorType,int32_t errorCode)417 void ImageSinkDecoder::OnError(Media::AVCodecErrorType errorType, int32_t errorCode)
418 {
419 DHLOGI("%s: OnImageDecodeError, errorType:%" PRId32", errorCode:%" PRId32, LOG_TAG, errorType, errorCode);
420 std::shared_ptr<IImageSinkProcessorListener> listener = imageProcessorListener_.lock();
421 if (listener == nullptr) {
422 DHLOGE("%s: Listener is null.", LOG_TAG);
423 return;
424 }
425 listener->OnProcessorStateNotify(errorCode);
426 }
427
OnInputBufferAvailable(uint32_t index)428 void ImageSinkDecoder::OnInputBufferAvailable(uint32_t index)
429 {
430 DHLOGI("%s: OnDecodeInputBufferAvailable: %u.", LOG_TAG, index);
431 std::lock_guard<std::mutex> dataLock(dataMutex_);
432 bufferIndexQueue_.push(index);
433 }
434
OnOutputBufferAvailable(uint32_t index,Media::AVCodecBufferInfo info,Media::AVCodecBufferFlag flag)435 void ImageSinkDecoder::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info,
436 Media::AVCodecBufferFlag flag)
437 {
438 DHLOGI("%s: OnDecodeOutputBufferAvailable.", LOG_TAG);
439 if (videoDecoder_ == nullptr) {
440 DHLOGE("%s: Decoder is null.", LOG_TAG);
441 return;
442 }
443
444 decoderBufferInfo_ = info;
445 int32_t ret = videoDecoder_->ReleaseOutputBuffer(index, true);
446 if (ret != Media::MSERR_OK) {
447 DHLOGD("%s: ReleaseOutputBuffer failed.", LOG_TAG);
448 }
449 }
450
OnOutputFormatChanged(const Media::Format & format)451 void ImageSinkDecoder::OnOutputFormatChanged(const Media::Format &format)
452 {
453 (void) format;
454 }
455
StartInputThread()456 int32_t ImageSinkDecoder::StartInputThread()
457 {
458 DHLOGI("%s: StartInputThread.", LOG_TAG);
459 isDecoderReady_ = true;
460 decodeThread_ = std::thread(&ImageSinkDecoder::DecodeScreenData, this);
461 return DH_SUCCESS;
462 }
463
StopInputThread()464 int32_t ImageSinkDecoder::StopInputThread()
465 {
466 DHLOGI("%s: StopInputThread.", LOG_TAG);
467 isDecoderReady_ = false;
468 if (decodeThread_.joinable()) {
469 decodeThread_.join();
470 }
471 std::lock_guard<std::mutex> dataLock(dataMutex_);
472 while (!bufferIndexQueue_.empty()) {
473 bufferIndexQueue_.pop();
474 }
475 while (!videoDataQueue_.empty()) {
476 videoDataQueue_.pop();
477 }
478
479 return DH_SUCCESS;
480 }
481
DecodeScreenData()482 void ImageSinkDecoder::DecodeScreenData()
483 {
484 DHLOGI("%s: DecodeScreenData.", LOG_TAG);
485 int32_t ret = pthread_setname_np(pthread_self(), DECODE_THREAD);
486 if (ret != DH_SUCCESS) {
487 DHLOGE("ImageSinkDecoder set thread name failed, ret %" PRId32, ret);
488 }
489 while (isDecoderReady_) {
490 std::shared_ptr<DataBuffer> screenData;
491 int32_t bufferIndex = 0;
492 {
493 std::unique_lock<std::mutex> lock(dataMutex_);
494 decodeCond_.wait_for(lock, std::chrono::milliseconds(DECODE_WAIT_MILLISECONDS),
495 [this]() { return (!videoDataQueue_.empty() && !bufferIndexQueue_.empty()); });
496
497 if (videoDataQueue_.empty() || bufferIndexQueue_.empty()) {
498 DHLOGD("%s: Index queue or data queue is empty.", LOG_TAG);
499 continue;
500 }
501 bufferIndex = bufferIndexQueue_.front();
502 bufferIndexQueue_.pop();
503 screenData = videoDataQueue_.front();
504 videoDataQueue_.pop();
505 }
506
507 ret = ProcessData(screenData, bufferIndex);
508 if (ret == ERR_DH_SCREEN_TRANS_NULL_VALUE) {
509 return;
510 } else if (ret != DH_SUCCESS) {
511 continue;
512 }
513 }
514 }
515
ProcessData(const std::shared_ptr<DataBuffer> & screenData,const int32_t bufferIndex)516 int32_t ImageSinkDecoder::ProcessData(const std::shared_ptr<DataBuffer> &screenData, const int32_t bufferIndex)
517 {
518 DHLOGI("%s: ProcessData.", LOG_TAG);
519 if (videoDecoder_ == nullptr || screenData == nullptr) {
520 DHLOGE("%s: Decoder or screenData is null.", LOG_TAG);
521 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
522 }
523
524 auto inputBuffer = videoDecoder_->GetInputBuffer(bufferIndex);
525 if (inputBuffer == nullptr) {
526 DHLOGE("%s: GetInputBuffer failed.", LOG_TAG);
527 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
528 }
529
530 int32_t ret = memcpy_s(inputBuffer->GetBase(), inputBuffer->GetSize(), screenData->Data(), screenData->Capacity());
531 if (ret != EOK) {
532 DHLOGE("%s: Copy data failed.", LOG_TAG);
533 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
534 }
535
536 DHLOGD("%s: Decode screen data. send data to H264 decoder", LOG_TAG);
537 Media::AVCodecBufferInfo bufferInfo;
538 bufferInfo.presentationTimeUs = 0;
539 bufferInfo.size = static_cast<int32_t>(screenData->Capacity());
540 bufferInfo.offset = 0;
541 ret = videoDecoder_->QueueInputBuffer(bufferIndex, bufferInfo, Media::AVCODEC_BUFFER_FLAG_NONE);
542 if (ret != Media::MSERR_OK) {
543 DHLOGE("%s: QueueInputBuffer failed.", LOG_TAG);
544 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
545 }
546 return DH_SUCCESS;
547 }
548 } // namespace DistributedHardware
549 } // namespace OHOS
550