1da853ecaSopenharmony_ci/*
2da853ecaSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License.
5da853ecaSopenharmony_ci * You may obtain a copy of the License at
6da853ecaSopenharmony_ci *
7da853ecaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8da853ecaSopenharmony_ci *
9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and
13da853ecaSopenharmony_ci * limitations under the License.
14da853ecaSopenharmony_ci */
15da853ecaSopenharmony_ci#include <cstddef>
16da853ecaSopenharmony_ci#include <cstdint>
17da853ecaSopenharmony_ci#include "native_avcodec_videodecoder.h"
18da853ecaSopenharmony_ci#include "native_averrors.h"
19da853ecaSopenharmony_ci#include "native_avcodec_base.h"
20da853ecaSopenharmony_ci#include "videodec_sample.h"
21da853ecaSopenharmony_ciusing namespace std;
22da853ecaSopenharmony_ciusing namespace OHOS;
23da853ecaSopenharmony_ciusing namespace OHOS::Media;
24da853ecaSopenharmony_ci#define FUZZ_PROJECT_NAME "hwdecoder_fuzzer"
25da853ecaSopenharmony_ci
26da853ecaSopenharmony_cistatic VDecFuzzSample *g_vDecSample = nullptr;
27da853ecaSopenharmony_ciconstexpr uint32_t DEFAULT_WIDTH = 1920;
28da853ecaSopenharmony_ciconstexpr uint32_t DEFAULT_HEIGHT = 1080;
29da853ecaSopenharmony_ciconstexpr uint32_t SPS_SIZE = 0x19;
30da853ecaSopenharmony_ciconstexpr uint32_t PPS_SIZE = 0x05;
31da853ecaSopenharmony_ciconstexpr uint32_t START_CODE_SIZE = 4;
32da853ecaSopenharmony_ciconstexpr uint8_t SPS[SPS_SIZE + START_CODE_SIZE] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x28, 0xAC,
33da853ecaSopenharmony_ci                                                     0xB4, 0x03, 0xC0, 0x11, 0x3F, 0x2E, 0x02, 0x20, 0x00,
34da853ecaSopenharmony_ci                                                     0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x07, 0x81, 0xE3,
35da853ecaSopenharmony_ci                                                     0x06, 0x54};
36da853ecaSopenharmony_ciconstexpr uint8_t PPS[PPS_SIZE + START_CODE_SIZE] = {0x00, 0x00, 0x00, 0x01, 0x68, 0xEF, 0x0F, 0x2C, 0x8B};
37da853ecaSopenharmony_cibool g_isSurfMode = true;
38da853ecaSopenharmony_ci
39da853ecaSopenharmony_civoid RunNormalDecoder()
40da853ecaSopenharmony_ci{
41da853ecaSopenharmony_ci    VDecFuzzSample *vDecSample = new VDecFuzzSample();
42da853ecaSopenharmony_ci    vDecSample->defaultWidth = DEFAULT_WIDTH;
43da853ecaSopenharmony_ci    vDecSample->defaultHeight = DEFAULT_HEIGHT;
44da853ecaSopenharmony_ci    vDecSample->CreateVideoDecoder();
45da853ecaSopenharmony_ci    vDecSample->ConfigureVideoDecoder();
46da853ecaSopenharmony_ci    vDecSample->SetVideoDecoderCallback();
47da853ecaSopenharmony_ci    vDecSample->StartVideoDecoder();
48da853ecaSopenharmony_ci    vDecSample->WaitForEOS();
49da853ecaSopenharmony_ci    delete vDecSample;
50da853ecaSopenharmony_ci
51da853ecaSopenharmony_ci    vDecSample = new VDecFuzzSample();
52da853ecaSopenharmony_ci    vDecSample->isSurfMode = true;
53da853ecaSopenharmony_ci    vDecSample->defaultWidth = DEFAULT_WIDTH;
54da853ecaSopenharmony_ci    vDecSample->defaultHeight = DEFAULT_HEIGHT;
55da853ecaSopenharmony_ci    vDecSample->CreateVideoDecoder();
56da853ecaSopenharmony_ci    vDecSample->ConfigureVideoDecoder();
57da853ecaSopenharmony_ci    vDecSample->SetVideoDecoderCallback();
58da853ecaSopenharmony_ci    vDecSample->StartVideoDecoder();
59da853ecaSopenharmony_ci    vDecSample->WaitForEOS();
60da853ecaSopenharmony_ci    delete vDecSample;
61da853ecaSopenharmony_ci}
62da853ecaSopenharmony_ci
63da853ecaSopenharmony_cibool g_needRunNormalDecoder = true;
64da853ecaSopenharmony_cinamespace OHOS {
65da853ecaSopenharmony_cibool HwdecoderFuzzTest(const uint8_t *data, size_t size)
66da853ecaSopenharmony_ci{
67da853ecaSopenharmony_ci    if (size < sizeof(int32_t)) {
68da853ecaSopenharmony_ci        return false;
69da853ecaSopenharmony_ci    }
70da853ecaSopenharmony_ci    if (g_needRunNormalDecoder) {
71da853ecaSopenharmony_ci        g_needRunNormalDecoder = false;
72da853ecaSopenharmony_ci        RunNormalDecoder();
73da853ecaSopenharmony_ci    }
74da853ecaSopenharmony_ci    int32_t data_ = *reinterpret_cast<const int32_t *>(data);
75da853ecaSopenharmony_ci    if (!g_vDecSample) {
76da853ecaSopenharmony_ci        g_vDecSample = new VDecFuzzSample();
77da853ecaSopenharmony_ci        g_vDecSample->defaultWidth = DEFAULT_WIDTH;
78da853ecaSopenharmony_ci        g_vDecSample->defaultHeight = DEFAULT_HEIGHT;
79da853ecaSopenharmony_ci        g_vDecSample->CreateVideoDecoder();
80da853ecaSopenharmony_ci        g_vDecSample->ConfigureVideoDecoder();
81da853ecaSopenharmony_ci        g_vDecSample->SetVideoDecoderCallback();
82da853ecaSopenharmony_ci        g_vDecSample->Start();
83da853ecaSopenharmony_ci        g_vDecSample->InputFuncFUZZ(SPS, SPS_SIZE + START_CODE_SIZE);
84da853ecaSopenharmony_ci        g_vDecSample->InputFuncFUZZ(PPS, PPS_SIZE + START_CODE_SIZE);
85da853ecaSopenharmony_ci    }
86da853ecaSopenharmony_ci    OH_AVErrCode ret = g_vDecSample->InputFuncFUZZ(data, size);
87da853ecaSopenharmony_ci    g_vDecSample->SetParameter(data_);
88da853ecaSopenharmony_ci    if (ret == AV_ERR_NO_MEMORY) {
89da853ecaSopenharmony_ci        g_vDecSample->Flush();
90da853ecaSopenharmony_ci        g_vDecSample->Stop();
91da853ecaSopenharmony_ci        g_vDecSample->Reset();
92da853ecaSopenharmony_ci        delete g_vDecSample;
93da853ecaSopenharmony_ci        g_vDecSample = nullptr;
94da853ecaSopenharmony_ci        return false;
95da853ecaSopenharmony_ci    }
96da853ecaSopenharmony_ci    return true;
97da853ecaSopenharmony_ci}
98da853ecaSopenharmony_ci} // namespace OHOS
99da853ecaSopenharmony_ci
100da853ecaSopenharmony_ci/* Fuzzer entry point */
101da853ecaSopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
102da853ecaSopenharmony_ci{
103da853ecaSopenharmony_ci    /* Run your code on data */
104da853ecaSopenharmony_ci    OHOS::HwdecoderFuzzTest(data, size);
105da853ecaSopenharmony_ci    return 0;
106da853ecaSopenharmony_ci}
107