• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #include <arpa/inet.h>
16 #include <sys/time.h>
17 #include <utility>
18 #include "videodec_sample.h"
19 using namespace OHOS;
20 using namespace OHOS::Media;
21 using namespace std;
22 namespace {
23 const string MIME_TYPE = "video/mp4v-es";
24 constexpr int64_t NANOS_IN_SECOND = 1000000000L;
25 constexpr int64_t NANOS_IN_MICRO = 1000L;
26 constexpr uint32_t PREREAD_BUFFER_SIZE = 0.1 * 1024 * 1024;
27 constexpr uint8_t MPEG4_FRAME_HEAD[] = {0x00, 0x00, 0x01, 0xb6};
28 constexpr uint8_t MPEG4_SEQUENCE_HEAD[] = {0x00, 0x00, 0x01, 0xb0};
29 constexpr uint32_t START_CODE_SIZE = 4;
30 constexpr uint32_t MAX_WIDTH = 4000;
31 constexpr uint32_t MAX_HEIGHT = 3000;
32 constexpr uint32_t MAX_NALU_SIZE = MAX_WIDTH * MAX_HEIGHT << 1;
33 VDecFuzzSample *g_decSample = nullptr;
34 
35 bool g_fuzzError = false;
36 
clearIntqueue(std::queue<uint32_t> & q)37 void clearIntqueue(std::queue<uint32_t> &q)
38 {
39     std::queue<uint32_t> empty;
40     swap(empty, q);
41 }
42 
clearBufferqueue(std::queue<OH_AVCodecBufferAttr> & q)43 void clearBufferqueue(std::queue<OH_AVCodecBufferAttr> &q)
44 {
45     std::queue<OH_AVCodecBufferAttr> empty;
46     swap(empty, q);
47 }
48 
clearAvBufferQueue(std::queue<OH_AVMemory * > & q)49 void clearAvBufferQueue(std::queue<OH_AVMemory *> &q)
50 {
51     std::queue<OH_AVMemory *> empty;
52     swap(empty, q);
53 }
54 } // namespace
55 
56 class TestConsumerListener : public IBufferConsumerListener {
57 public:
TestConsumerListener(sptr<Surface> cs)58     TestConsumerListener(sptr<Surface> cs) : cs(cs) {};
~TestConsumerListener()59     ~TestConsumerListener() {}
OnBufferAvailable()60     void OnBufferAvailable() override
61     {
62         sptr<SurfaceBuffer> buffer;
63         int32_t flushFence;
64         cs->AcquireBuffer(buffer, flushFence, timestamp, damage);
65 
66         cs->ReleaseBuffer(buffer, -1);
67     }
68 
69 private:
70     int64_t timestamp = 0;
71     Rect damage = {};
72     sptr<Surface> cs {nullptr};
73 };
74 
~VDecFuzzSample()75 VDecFuzzSample::~VDecFuzzSample()
76 {
77     Release();
78 }
79 
VdecError(OH_AVCodec * codec,int32_t errorCode,void * userData)80 void VdecError(OH_AVCodec *codec, int32_t errorCode, void *userData)
81 {
82     VDecSignal *signal = static_cast<VDecSignal *>(userData);
83     if (signal == nullptr) {
84         return;
85     }
86     cout << "Error errorCode=" << errorCode << endl;
87     g_fuzzError = true;
88     g_decSample->isRunning_.store(false);
89     signal->inCond_.notify_all();
90 }
91 
VdecFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)92 void VdecFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
93 {
94     cout << "Format Changed" << endl;
95     int32_t currentWidth = 0;
96     int32_t currentHeight = 0;
97     OH_AVFormat_GetIntValue(format, OH_MD_KEY_WIDTH, &currentWidth);
98     OH_AVFormat_GetIntValue(format, OH_MD_KEY_HEIGHT, &currentHeight);
99     g_decSample->defaultWidth = currentWidth;
100     g_decSample->defaultHeight = currentHeight;
101 }
102 
VdecInputDataReady(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,void * userData)103 void VdecInputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData)
104 {
105     VDecSignal *signal = static_cast<VDecSignal *>(userData);
106     if (signal == nullptr) {
107         return;
108     }
109     unique_lock<mutex> lock(signal->inMutex_);
110     signal->inIdxQueue_.push(index);
111     signal->inBufferQueue_.push(data);
112     signal->inCond_.notify_all();
113 }
114 
VdecOutputDataReady(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)115 void VdecOutputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, OH_AVCodecBufferAttr *attr,
116                          void *userData)
117 {
118     VDecSignal *signal = static_cast<VDecSignal *>(userData);
119     if (signal == nullptr) {
120         return;
121     }
122     unique_lock<mutex> lock(signal->outMutex_);
123     signal->outIdxQueue_.push(index);
124     signal->attrQueue_.push(*attr);
125     signal->outBufferQueue_.push(data);
126     signal->outCond_.notify_all();
127     if (g_decSample->isSurfMode) {
128         OH_VideoDecoder_RenderOutputData(codec, index);
129     } else {
130         OH_VideoDecoder_FreeOutputData(codec, index);
131     }
132 }
133 
GetSystemTimeUs()134 int64_t VDecFuzzSample::GetSystemTimeUs()
135 {
136     struct timespec now;
137     (void)clock_gettime(CLOCK_BOOTTIME, &now);
138     int64_t nanoTime = static_cast<int64_t>(now.tv_sec) * NANOS_IN_SECOND + now.tv_nsec;
139     return nanoTime / NANOS_IN_MICRO;
140 }
141 
ConfigureVideoDecoder()142 int32_t VDecFuzzSample::ConfigureVideoDecoder()
143 {
144     if (isSurfMode) {
145         cs = Surface::CreateSurfaceAsConsumer();
146         sptr<IBufferConsumerListener> listener = new TestConsumerListener(cs);
147         cs->RegisterConsumerListener(listener);
148         auto p = cs->GetProducer();
149         ps = Surface::CreateSurfaceAsProducer(p);
150         nativeWindow = CreateNativeWindowFromSurface(&ps);
151         OH_VideoDecoder_SetSurface(vdec_, nativeWindow);
152     }
153     OH_AVFormat *format = OH_AVFormat_Create();
154     if (format == nullptr) {
155         cout << "Fatal: Failed to create format" << endl;
156         return AV_ERR_UNKNOWN;
157     }
158     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, defaultWidth);
159     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, defaultHeight);
160     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, defaultFrameRate);
161     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, defaultRotation);
162     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, defaultPixelFormat);
163     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_DECODER_BLANK_FRAME_ON_SHUTDOWN, enbleBlankFrame);
164     int ret = OH_VideoDecoder_Configure(vdec_, format);
165     OH_AVFormat_Destroy(format);
166     return ret;
167 }
168 
RunVideoDec(string codeName)169 int32_t VDecFuzzSample::RunVideoDec(string codeName)
170 {
171     int err = CreateVideoDecoder(codeName);
172     if (err != AV_ERR_OK) {
173         cout << "Failed to create video decoder" << endl;
174         return err;
175     }
176     err = ConfigureVideoDecoder();
177     if (err != AV_ERR_OK) {
178         cout << "Failed to configure video decoder" << endl;
179         Release();
180         return err;
181     }
182     err = SetVideoDecoderCallback();
183     if (err != AV_ERR_OK) {
184         cout << "Failed to setCallback" << endl;
185         Release();
186         return err;
187     }
188     err = StartVideoDecoder();
189     if (err != AV_ERR_OK) {
190         cout << "Failed to start video decoder" << endl;
191         Release();
192         return err;
193     }
194     return err;
195 }
196 
SetVideoDecoderCallback()197 int32_t VDecFuzzSample::SetVideoDecoderCallback()
198 {
199     signal_ = new VDecSignal();
200     if (signal_ == nullptr) {
201         cout << "Failed to new VDecSignal" << endl;
202         return AV_ERR_UNKNOWN;
203     }
204 
205     cb_.onError = VdecError;
206     cb_.onStreamChanged = VdecFormatChanged;
207     cb_.onNeedInputData = VdecInputDataReady;
208     cb_.onNeedOutputData = VdecOutputDataReady;
209     return OH_VideoDecoder_SetCallback(vdec_, cb_, static_cast<void *>(signal_));
210 }
211 
ReleaseInFile()212 void VDecFuzzSample::ReleaseInFile()
213 {
214     if (inFile_ != nullptr) {
215         if (inFile_->is_open()) {
216             inFile_->close();
217         }
218         inFile_.reset();
219         inFile_ = nullptr;
220     }
221 }
222 
StopInloop()223 void VDecFuzzSample::StopInloop()
224 {
225     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
226         unique_lock<mutex> lock(signal_->inMutex_);
227         clearIntqueue(signal_->inIdxQueue_);
228         signal_->inCond_.notify_all();
229         lock.unlock();
230 
231         inputLoop_->join();
232         inputLoop_.reset();
233     }
234 }
235 
StartVideoDecoder()236 int32_t VDecFuzzSample::StartVideoDecoder()
237 {
238     int ret = OH_VideoDecoder_Start(vdec_);
239     if (ret != AV_ERR_OK) {
240         cout << "Failed to start codec" << endl;
241         return ret;
242     }
243 
244     isRunning_.store(true);
245 
246     inFile_ = make_unique<ifstream>();
247     if (inFile_ == nullptr) {
248         isRunning_.store(false);
249         (void)OH_VideoDecoder_Stop(vdec_);
250         return AV_ERR_UNKNOWN;
251     }
252     inFile_->open(inpDir, ios::in | ios::binary);
253     if (!inFile_->is_open()) {
254         cout << "open input file failed" << endl;
255         isRunning_.store(false);
256         (void)OH_VideoDecoder_Stop(vdec_);
257         inFile_->close();
258         inFile_.reset();
259         inFile_ = nullptr;
260         return AV_ERR_UNKNOWN;
261     }
262 
263     inputLoop_ = make_unique<thread>(&VDecFuzzSample::InputFuncAVCC, this);
264     if (inputLoop_ == nullptr) {
265         cout << "Failed to create input loop" << endl;
266         isRunning_.store(false);
267         (void)OH_VideoDecoder_Stop(vdec_);
268         ReleaseInFile();
269         return AV_ERR_UNKNOWN;
270     }
271     return AV_ERR_OK;
272 }
273 
CreateVideoDecoder(string codeName)274 int32_t VDecFuzzSample::CreateVideoDecoder(string codeName)
275 {
276     vdec_ = OH_VideoDecoder_CreateByName("aabbcc");
277     if (vdec_) {
278         OH_VideoDecoder_Destroy(vdec_);
279         vdec_ = nullptr;
280     }
281     OH_AVCodec *tmpDec = OH_VideoDecoder_CreateByMime("aabbcc");
282     if (tmpDec) {
283         OH_VideoDecoder_Destroy(tmpDec);
284         tmpDec = nullptr;
285     }
286     tmpDec = OH_VideoDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
287     if (tmpDec) {
288         OH_VideoDecoder_Destroy(tmpDec);
289         tmpDec = nullptr;
290     }
291     vdec_ = OH_VideoDecoder_CreateByName(codeName.c_str());
292     g_decSample = this;
293     return vdec_ == nullptr ? AV_ERR_UNKNOWN : AV_ERR_OK;
294 }
295 
WaitForEOS()296 void VDecFuzzSample::WaitForEOS()
297 {
298     if (inputLoop_ && inputLoop_->joinable()) {
299         inputLoop_->join();
300     }
301 }
302 
PtrStep(uint32_t & bufferSize,unsigned char ** pBuffer,uint32_t size)303 void VDecFuzzSample::PtrStep(uint32_t &bufferSize, unsigned char **pBuffer, uint32_t size)
304 {
305     pPrereadBuffer_ += size;
306     bufferSize += size;
307     *pBuffer += size;
308 }
309 
PtrStepExtraRead(uint32_t & bufferSize,unsigned char ** pBuffer)310 void VDecFuzzSample::PtrStepExtraRead(uint32_t &bufferSize, unsigned char **pBuffer)
311 {
312     bufferSize -= START_CODE_SIZE;
313     *pBuffer -= START_CODE_SIZE;
314     pPrereadBuffer_ = 0;
315 }
316 
GetBufferSize()317 void VDecFuzzSample::GetBufferSize()
318 {
319     auto pBuffer = mpegUnit_->data();
320     uint32_t bufferSize = 0;
321     mpegUnit_->resize(MAX_NALU_SIZE);
322     do {
323         auto pos1 = std::search(prereadBuffer_.get() + pPrereadBuffer_ + START_CODE_SIZE,
324             prereadBuffer_.get() + prereadBufferSize_, std::begin(MPEG4_FRAME_HEAD), std::end(MPEG4_FRAME_HEAD));
325         uint32_t size1 = std::distance(prereadBuffer_.get() + pPrereadBuffer_, pos1);
326         auto pos2 = std::search(prereadBuffer_.get() + pPrereadBuffer_, prereadBuffer_.get() +
327             pPrereadBuffer_ + size1, std::begin(MPEG4_SEQUENCE_HEAD), std::end(MPEG4_SEQUENCE_HEAD));
328         uint32_t size = std::distance(prereadBuffer_.get() + pPrereadBuffer_, pos2);
329         if (size == 0) {
330             auto pos3 = std::search(prereadBuffer_.get() + pPrereadBuffer_ + size1 + START_CODE_SIZE,
331             prereadBuffer_.get() + prereadBufferSize_, std::begin(MPEG4_FRAME_HEAD), std::end(MPEG4_FRAME_HEAD));
332             uint32_t size2 = std::distance(prereadBuffer_.get() + pPrereadBuffer_, pos3);
333             if (memcpy_s(pBuffer, size2, prereadBuffer_.get() + pPrereadBuffer_, size2) != EOK) {
334                 return;
335             }
336             PtrStep(bufferSize, &pBuffer, size2);
337             if (!((pPrereadBuffer_ == prereadBufferSize_) && !inFile_->eof())) {
338                 break;
339             }
340         } else if (size1 > size) {
341             if (memcpy_s(pBuffer, size, prereadBuffer_.get() + pPrereadBuffer_, size) != EOK) {
342                 return;
343             }
344             PtrStep(bufferSize, &pBuffer, size);
345             if (!((pPrereadBuffer_ == prereadBufferSize_) && !inFile_->eof())) {
346                 break;
347             }
348         } else {
349             if (memcpy_s(pBuffer, size1, prereadBuffer_.get() + pPrereadBuffer_, size1) != EOK) {
350                 return;
351             }
352             PtrStep(bufferSize, &pBuffer, size1);
353             if (!((pPrereadBuffer_ == prereadBufferSize_) && !inFile_->eof())) {
354                 break;
355             }
356         }
357         inFile_->read(reinterpret_cast<char *>(prereadBuffer_.get() + START_CODE_SIZE), PREREAD_BUFFER_SIZE);
358         prereadBufferSize_ = inFile_->gcount() + START_CODE_SIZE;
359         pPrereadBuffer_ = START_CODE_SIZE;
360         if (memcpy_s(prereadBuffer_.get(), START_CODE_SIZE, pBuffer - START_CODE_SIZE, START_CODE_SIZE) != EOK) {
361             return;
362         }
363         PtrStepExtraRead(bufferSize, &pBuffer);
364     } while (pPrereadBuffer_ != prereadBufferSize_);
365     mpegUnit_->resize(bufferSize);
366 }
367 
ReadData(uint32_t index,OH_AVMemory * buffer)368 int32_t VDecFuzzSample::ReadData(uint32_t index, OH_AVMemory *buffer)
369 {
370     uint32_t bufferSize = 0;
371     if (inFile_->tellg() == 0) {
372         inFile_->read(reinterpret_cast<char *>(prereadBuffer_.get() + START_CODE_SIZE), PREREAD_BUFFER_SIZE);
373         prereadBufferSize_ = inFile_->gcount() + START_CODE_SIZE;
374         pPrereadBuffer_ = START_CODE_SIZE;
375     }
376 
377     if (inFile_->eof() && finishLastPush) {
378         SetEOS(index);
379         mpegUnit_->resize(0);
380         return 1;
381     }
382 
383     GetBufferSize();
384     bufferSize = mpegUnit_->size();
385     return SendData(bufferSize, index, buffer);
386 }
387 
SendData(uint32_t bufferSize,uint32_t index,OH_AVMemory * buffer)388 uint32_t VDecFuzzSample::SendData(uint32_t bufferSize, uint32_t index, OH_AVMemory *buffer)
389 {
390     OH_AVCodecBufferAttr attr;
391     uint8_t *frameBuffer = nullptr;
392     if (bufferSize > 0) {
393         frameBuffer = new uint8_t[bufferSize];
394     } else {
395         delete[] frameBuffer;
396         return 0;
397     }
398     memcpy_s(frameBuffer, bufferSize, mpegUnit_->data(), bufferSize);
399     attr.pts = GetSystemTimeUs();
400     attr.size = bufferSize;
401     attr.offset = 0;
402     attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
403 
404     if (pPrereadBuffer_ == prereadBufferSize_ && inFile_->eof()) {
405         finishLastPush = true;
406     }
407     int32_t size = OH_AVMemory_GetSize(buffer);
408     if (size < attr.size) {
409         delete[] frameBuffer;
410         cout << "ERROR:AVMemory not enough, buffer size" << attr.size << "   AVMemory Size " << size << endl;
411         isRunning_.store(false);
412         return 1;
413     }
414     uint8_t *bufferAddr = OH_AVMemory_GetAddr(buffer);
415     if (memcpy_s(bufferAddr, size, frameBuffer, attr.size) != EOK) {
416         delete[] frameBuffer;
417         cout << "Fatal: memcpy fail" << endl;
418         isRunning_.store(false);
419         return 1;
420     }
421     delete[] frameBuffer;
422 
423     int ret = OH_VideoDecoder_PushInputData(vdec_, index, attr);
424     if (ret != AV_ERR_OK) {
425         errCount++;
426         cout << "push input data failed, error:" << ret << endl;
427     }
428 
429     if (inFile_->eof() && finishLastPush && repeatRun) {
430         inFile_->clear();
431         inFile_->seekg(0, ios::beg);
432         finishLastPush = false;
433         cout << "repeat" << endl;
434         return 0;
435     }
436 
437     frameCount_ = frameCount_ + 1;
438     return 0;
439 }
440 
InputFuncAVCC()441 void VDecFuzzSample::InputFuncAVCC()
442 {
443     frameCount_ = 1;
444     errCount = 0;
445     while (true) {
446         if (!isRunning_.load()) {
447             break;
448         }
449         unique_lock<mutex> lock(signal_->inMutex_);
450         signal_->inCond_.wait(lock, [this]() {
451             if (!isRunning_.load()) {
452                 cout << "quit signal" << endl;
453                 return true;
454             }
455             return signal_->inIdxQueue_.size() > 0;
456         });
457         if (!isRunning_.load()) {
458             break;
459         }
460         uint32_t index = signal_->inIdxQueue_.front();
461         auto buffer = signal_->inBufferQueue_.front();
462         signal_->inIdxQueue_.pop();
463         signal_->inBufferQueue_.pop();
464         lock.unlock();
465         int ret = ReadData(index, buffer);
466         if (ret == 1) {
467             break;
468         }
469     }
470 }
471 
InputFuncFUZZ(const uint8_t * data,size_t size)472 OH_AVErrCode VDecFuzzSample::InputFuncFUZZ(const uint8_t *data, size_t size)
473 {
474     if (!isRunning_.load())
475         return AV_ERR_TIMEOUT;
476     uint32_t index;
477     unique_lock<mutex> lock(signal_->inMutex_);
478     signal_->inCond_.wait(lock, [this]() {
479         if (!isRunning_.load()) {
480             return true;
481         }
482         return signal_->inIdxQueue_.size() > 0;
483     });
484     if (!isRunning_.load())
485         return AV_ERR_TIMEOUT;
486     index = signal_->inIdxQueue_.front();
487     auto buffer = signal_->inBufferQueue_.front();
488     signal_->inIdxQueue_.pop();
489     signal_->inBufferQueue_.pop();
490     lock.unlock();
491     int32_t bufferSize = OH_AVMemory_GetSize(buffer);
492     uint8_t *bufferAddr = OH_AVMemory_GetAddr(buffer);
493 
494     if (memcpy_s(bufferAddr, bufferSize, data, size) != EOK) {
495         cout << "Fatal: memcpy fail" << endl;
496         return AV_ERR_NO_MEMORY;
497     }
498     OH_AVCodecBufferAttr attr;
499     attr.pts = GetSystemTimeUs();
500     attr.size = bufferSize;
501     attr.offset = 0;
502     attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
503     OH_AVErrCode ret = OH_VideoDecoder_PushInputData(vdec_, index, attr);
504     return ret;
505 }
506 
SetEOS(uint32_t index)507 void VDecFuzzSample::SetEOS(uint32_t index)
508 {
509     OH_AVCodecBufferAttr attr;
510     attr.pts = 0;
511     attr.size = 0;
512     attr.offset = 0;
513     attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
514     int32_t res = OH_VideoDecoder_PushInputData(vdec_, index, attr);
515     cout << "OH_VideoDecoder_PushInputData    EOS   res: " << res << endl;
516 }
517 
Flush()518 int32_t VDecFuzzSample::Flush()
519 {
520     unique_lock<mutex> inLock(signal_->inMutex_);
521     clearIntqueue(signal_->inIdxQueue_);
522     signal_->inCond_.notify_all();
523     inLock.unlock();
524     unique_lock<mutex> outLock(signal_->outMutex_);
525     clearIntqueue(signal_->outIdxQueue_);
526     clearBufferqueue(signal_->attrQueue_);
527     signal_->outCond_.notify_all();
528     isRunning_.store(false);
529     outLock.unlock();
530 
531     return OH_VideoDecoder_Flush(vdec_);
532 }
533 
Reset()534 int32_t VDecFuzzSample::Reset()
535 {
536     isRunning_.store(false);
537     StopInloop();
538     ReleaseInFile();
539     return OH_VideoDecoder_Reset(vdec_);
540 }
541 
Release()542 int32_t VDecFuzzSample::Release()
543 {
544     int ret = 0;
545     if (vdec_ != nullptr) {
546         ret = OH_VideoDecoder_Destroy(vdec_);
547         vdec_ = nullptr;
548     }
549     if (signal_ != nullptr) {
550         clearAvBufferQueue(signal_->inBufferQueue_);
551         clearAvBufferQueue(signal_->outBufferQueue_);
552         delete signal_;
553         signal_ = nullptr;
554     }
555     return ret;
556 }
557 
Stop()558 int32_t VDecFuzzSample::Stop()
559 {
560     StopInloop();
561     clearIntqueue(signal_->outIdxQueue_);
562     clearBufferqueue(signal_->attrQueue_);
563     ReleaseInFile();
564     return OH_VideoDecoder_Stop(vdec_);
565 }
566 
Start()567 int32_t VDecFuzzSample::Start()
568 {
569     int32_t ret = 0;
570     ret = OH_VideoDecoder_Start(vdec_);
571     if (ret == AV_ERR_OK) {
572         isRunning_.store(true);
573     }
574     return ret;
575 }
576 
SetParameter(OH_AVFormat * format)577 int32_t VDecFuzzSample::SetParameter(OH_AVFormat *format)
578 {
579     return OH_VideoDecoder_SetParameter(vdec_, format);
580 }