1/* 2 * Copyright (c) 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 <cstddef> 17#include <cstdint> 18#include <fcntl.h> 19#include <unistd.h> 20#include <sys/stat.h> 21#include "native_avdemuxer.h" 22#include "native_avformat.h" 23#include "native_avsource.h" 24#include "native_avmemory.h" 25 26#define FUZZ_PROJECT_NAME "demuxer_fuzzer" 27namespace OHOS { 28static int32_t g_width = 3840; 29static int32_t g_height = 2160; 30static int64_t GetFileSize(const char *fileName) 31{ 32 int64_t fileSize = 0; 33 if (fileName != nullptr) { 34 struct stat fileStatus {}; 35 if (stat(fileName, &fileStatus) == 0) { 36 fileSize = static_cast<int64_t>(fileStatus.st_size); 37 } 38 } 39 return fileSize; 40} 41 42static void SetVarValue(OH_AVCodecBufferAttr attr, const int &tarckType, bool &audioIsEnd, bool &videoIsEnd) 43{ 44 if (tarckType == MEDIA_TYPE_AUD && (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS)) { 45 audioIsEnd = true; 46 } 47 48 if (tarckType == MEDIA_TYPE_VID && (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS)) { 49 videoIsEnd = true; 50 } 51} 52 53void RunNormalDemuxer() 54{ 55 int tarckType = 0; 56 int32_t trackCount; 57 OH_AVCodecBufferAttr attr; 58 bool audioIsEnd = false; 59 bool videoIsEnd = false; 60 const char *file = "/data/test/media/01_video_audio.mp4"; 61 int fd = open(file, O_RDONLY); 62 int64_t size = GetFileSize(file); 63 OH_AVSource *source = OH_AVSource_CreateWithFD(fd, 0, size); 64 if (!source) { 65 close(fd); 66 return; 67 } 68 OH_AVDemuxer *demuxer = OH_AVDemuxer_CreateWithSource(source); 69 if (!demuxer) { 70 close(fd); 71 return; 72 } 73 OH_AVFormat *sourceFormat = OH_AVSource_GetSourceFormat(source); 74 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount); 75 for (int32_t index = 0; index < trackCount; index++) { 76 OH_AVDemuxer_SelectTrackByID(demuxer, index); 77 } 78 OH_AVMemory *memory = OH_AVMemory_Create(g_width * g_height); 79 while (!audioIsEnd || !videoIsEnd) { 80 for (int32_t index = 0; index < trackCount; index++) { 81 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index); 82 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &tarckType); 83 if ((audioIsEnd && (tarckType == MEDIA_TYPE_AUD)) || (videoIsEnd && (tarckType == MEDIA_TYPE_VID))) { 84 continue; 85 } 86 if (trackFormat) { 87 OH_AVFormat_Destroy(trackFormat); 88 } 89 OH_AVDemuxer_ReadSample(demuxer, index, memory, &attr); 90 SetVarValue(attr, tarckType, audioIsEnd, videoIsEnd); 91 } 92 } 93 OH_AVDemuxer_Destroy(demuxer); 94 OH_AVSource_Destroy(source); 95 if (sourceFormat) { 96 OH_AVFormat_Destroy(sourceFormat); 97 } 98 if (memory) { 99 OH_AVMemory_Destroy(memory); 100 } 101 close(fd); 102} 103 104void RunNormalDemuxerApi11() 105{ 106 int tarckType = 0; 107 int32_t trackCount; 108 OH_AVCodecBufferAttr attr; 109 bool audioIsEnd = false; 110 bool videoIsEnd = false; 111 const char *file = "/data/test/media/01_video_audio.mp4"; 112 int fd = open(file, O_RDONLY); 113 int64_t size = GetFileSize(file); 114 OH_AVSource *source = OH_AVSource_CreateWithFD(fd, 0, size); 115 if (!source) { 116 close(fd); 117 return; 118 } 119 OH_AVDemuxer *demuxer = OH_AVDemuxer_CreateWithSource(source); 120 if (!demuxer) { 121 close(fd); 122 return; 123 } 124 OH_AVFormat *sourceFormat = OH_AVSource_GetSourceFormat(source); 125 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount); 126 for (int32_t index = 0; index < trackCount; index++) { 127 OH_AVDemuxer_SelectTrackByID(demuxer, index); 128 } 129 OH_AVBuffer *buffer = OH_AVBuffer_Create(g_width * g_height); 130 while (!audioIsEnd || !videoIsEnd) { 131 for (int32_t index = 0; index < trackCount; index++) { 132 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index); 133 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &tarckType); 134 if ((audioIsEnd && (tarckType == MEDIA_TYPE_AUD)) || (videoIsEnd && (tarckType == MEDIA_TYPE_VID))) { 135 continue; 136 } 137 if (trackFormat) { 138 OH_AVFormat_Destroy(trackFormat); 139 } 140 OH_AVDemuxer_ReadSampleBuffer(demuxer, index, buffer); 141 OH_AVBuffer_GetBufferAttr(buffer, &attr); 142 SetVarValue(attr, tarckType, audioIsEnd, videoIsEnd); 143 } 144 } 145 OH_AVDemuxer_Destroy(demuxer); 146 OH_AVSource_Destroy(source); 147 if (sourceFormat) { 148 OH_AVFormat_Destroy(sourceFormat); 149 } 150 if (buffer) { 151 OH_AVBuffer_Destroy(buffer); 152 } 153 close(fd); 154} 155 156bool DoSomethingInterestingWithMyAPI(const uint8_t *data, size_t size) 157{ 158 if (size < sizeof(int64_t)) { 159 return false; 160 } 161 RunNormalDemuxer(); 162 RunNormalDemuxerApi11(); 163 // FUZZ CreateFD 164 int32_t fd = *reinterpret_cast<const int32_t *>(data); 165 int64_t offset = *reinterpret_cast<const int64_t *>(data); 166 int64_t fileSize = *reinterpret_cast<const int64_t *>(data); 167 OH_AVSource *source = OH_AVSource_CreateWithFD(fd, offset, fileSize); 168 if (source) { 169 OH_AVSource_Destroy(source); 170 } 171 return true; 172} 173} // namespace OHOS 174 175/* Fuzzer entry point */ 176extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 177{ 178 /* Run your code on data */ 179 OHOS::DoSomethingInterestingWithMyAPI(data, size); 180 return 0; 181} 182