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