Akshata Kadam | 9d946be | 2022-07-06 09:25:38 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright (C) 2022 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | #include <NdkMediaCodecFuzzerBase.h> |
| 17 | |
| 18 | static const std::string kMimeTypes[] = { |
| 19 | MIMETYPE_AUDIO_AMR_NB, MIMETYPE_AUDIO_AMR_WB, MIMETYPE_AUDIO_MPEG, |
| 20 | MIMETYPE_AUDIO_AAC, MIMETYPE_AUDIO_FLAC, MIMETYPE_AUDIO_VORBIS, |
| 21 | MIMETYPE_AUDIO_OPUS, MIMETYPE_AUDIO_RAW, MIMETYPE_AUDIO_MSGSM, |
| 22 | MIMETYPE_AUDIO_EAC3, MIMETYPE_AUDIO_SCRAMBLED, MIMETYPE_VIDEO_VP8, |
| 23 | MIMETYPE_VIDEO_VP9, MIMETYPE_VIDEO_AV1, MIMETYPE_VIDEO_AVC, |
| 24 | MIMETYPE_VIDEO_HEVC, MIMETYPE_VIDEO_MPEG4, MIMETYPE_VIDEO_H263, |
| 25 | MIMETYPE_VIDEO_MPEG2, MIMETYPE_VIDEO_RAW, MIMETYPE_VIDEO_SCRAMBLED}; |
| 26 | |
| 27 | static const std::string kEncoderNames[] = { |
| 28 | "c2.android.avc.encoder", "c2.android.vp8.encoder", "c2.android.vp9.encoder", |
| 29 | "c2.android.hevc.encoder", "c2.android.mpeg2.encoder", "c2.android.mpeg4.encoder", |
| 30 | "c2.android.opus.encoder", "c2.android.amrnb.encoder", "c2.android.flac.encoder", |
| 31 | "c2.android.av1-aom.encoder"}; |
| 32 | |
| 33 | static const std::string kDecoderNames[] = {"c2.android.avc.decoder", |
| 34 | "c2.android.vp8.decoder", |
| 35 | "c2.android.vp9.decoder" |
| 36 | "c2.android.hevc.decoder", |
| 37 | "c2.android.mpeg2.decoder", |
| 38 | "c2.android.mpeg4.decoder", |
| 39 | "c2.android.opus.decoder", |
| 40 | "c2.android.amrnb.decoder", |
| 41 | "c2.android.flac.decoder", |
| 42 | "c2.android.av1-aom.decoder"}; |
| 43 | |
| 44 | static const std::string kFormatIntKeys[] = {AMEDIAFORMAT_KEY_BIT_RATE, |
| 45 | AMEDIAFORMAT_KEY_SAMPLE_RATE, |
| 46 | AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL, |
| 47 | AMEDIAFORMAT_KEY_CHANNEL_COUNT, |
| 48 | AMEDIAFORMAT_KEY_WIDTH, |
| 49 | AMEDIAFORMAT_KEY_HEIGHT, |
| 50 | AMEDIAFORMAT_KEY_FRAME_RATE, |
| 51 | AMEDIAFORMAT_KEY_COLOR_FORMAT, |
| 52 | AMEDIAFORMAT_VIDEO_QP_P_MIN, |
| 53 | AMEDIAFORMAT_VIDEO_QP_P_MAX, |
| 54 | AMEDIAFORMAT_VIDEO_QP_MIN, |
| 55 | AMEDIAFORMAT_VIDEO_QP_MAX, |
| 56 | AMEDIAFORMAT_VIDEO_QP_I_MIN, |
| 57 | AMEDIAFORMAT_VIDEO_QP_I_MAX, |
| 58 | AMEDIAFORMAT_VIDEO_QP_B_MIN, |
| 59 | AMEDIAFORMAT_VIDEO_QP_B_MAX, |
| 60 | AMEDIAFORMAT_KEY_VIDEO_QP_AVERAGE, |
| 61 | AMEDIAFORMAT_KEY_VIDEO_ENCODING_STATISTICS_LEVEL, |
| 62 | AMEDIAFORMAT_KEY_VALID_SAMPLES, |
| 63 | AMEDIAFORMAT_KEY_TRACK_INDEX, |
| 64 | AMEDIAFORMAT_KEY_TRACK_ID, |
| 65 | AMEDIAFORMAT_KEY_TILE_WIDTH, |
| 66 | AMEDIAFORMAT_KEY_TILE_HEIGHT, |
| 67 | AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH, |
| 68 | AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT, |
| 69 | AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, |
| 70 | AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT, |
| 71 | AMEDIAFORMAT_KEY_STRIDE, |
| 72 | AMEDIAFORMAT_KEY_SLICE_HEIGHT, |
| 73 | AMEDIAFORMAT_KEY_SAR_WIDTH, |
| 74 | AMEDIAFORMAT_KEY_SAR_HEIGHT, |
| 75 | AMEDIAFORMAT_KEY_ROTATION, |
| 76 | AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, |
| 77 | AMEDIAFORMAT_KEY_PROFILE, |
| 78 | AMEDIAFORMAT_KEY_PRIORITY, |
| 79 | AMEDIAFORMAT_KEY_PICTURE_TYPE, |
| 80 | AMEDIAFORMAT_KEY_PCM_ENCODING, |
| 81 | AMEDIAFORMAT_KEY_OPERATING_RATE, |
| 82 | AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT, |
| 83 | AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION, |
| 84 | AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER, |
| 85 | AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, |
| 86 | AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER, |
| 87 | AMEDIAFORMAT_KEY_LOW_LATENCY, |
| 88 | AMEDIAFORMAT_KEY_LOOP, |
| 89 | AMEDIAFORMAT_KEY_LEVEL, |
| 90 | AMEDIAFORMAT_KEY_LATENCY, |
| 91 | AMEDIAFORMAT_KEY_IS_SYNC_FRAME, |
| 92 | AMEDIAFORMAT_KEY_IS_DEFAULT, |
| 93 | AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD, |
| 94 | AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT, |
| 95 | AMEDIAFORMAT_KEY_GRID_ROWS, |
| 96 | AMEDIAFORMAT_KEY_GRID_COLUMNS, |
| 97 | AMEDIAFORMAT_KEY_FRAME_COUNT, |
| 98 | AMEDIAFORMAT_KEY_ENCODER_PADDING, |
| 99 | AMEDIAFORMAT_KEY_ENCODER_DELAY, |
| 100 | AMEDIAFORMAT_KEY_DISPLAY_WIDTH, |
| 101 | AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, |
| 102 | AMEDIAFORMAT_KEY_DISPLAY_CROP, |
| 103 | AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, |
| 104 | AMEDIAFORMAT_KEY_CRYPTO_MODE, |
| 105 | AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, |
| 106 | AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, |
| 107 | AMEDIAFORMAT_KEY_COLOR_TRANSFER, |
| 108 | AMEDIAFORMAT_KEY_COLOR_STANDARD, |
| 109 | AMEDIAFORMAT_KEY_COLOR_RANGE, |
| 110 | AMEDIAFORMAT_KEY_CHANNEL_MASK, |
| 111 | AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, |
| 112 | AMEDIAFORMAT_KEY_BITRATE_MODE, |
| 113 | AMEDIAFORMAT_KEY_AUDIO_SESSION_ID, |
| 114 | AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PROGRAM_ID, |
| 115 | AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_PRESENTATION_ID, |
| 116 | AMEDIAFORMAT_KEY_AAC_SBR_MODE, |
| 117 | AMEDIAFORMAT_KEY_AAC_PROFILE, |
| 118 | AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, |
| 119 | AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL, |
| 120 | AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, |
| 121 | AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION, |
| 122 | AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR, |
| 123 | AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR, |
| 124 | AMEDIAFORMAT_KEY_XMP_SIZE, |
| 125 | AMEDIAFORMAT_KEY_XMP_OFFSET, |
| 126 | AMEDIAFORMAT_KEY_TIME_US, |
| 127 | AMEDIAFORMAT_KEY_THUMBNAIL_TIME, |
| 128 | AMEDIAFORMAT_KEY_TARGET_TIME, |
| 129 | AMEDIAFORMAT_KEY_SAMPLE_TIME_BEFORE_APPEND, |
| 130 | AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET, |
| 131 | AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK, |
| 132 | AMEDIAFORMAT_KEY_EXIF_SIZE, |
| 133 | AMEDIAFORMAT_KEY_EXIF_OFFSET, |
| 134 | AMEDIAFORMAT_KEY_DURATION}; |
| 135 | |
| 136 | static const std::string kFormatBufferKeys[] = { |
| 137 | AMEDIAFORMAT_KEY_THUMBNAIL_CSD_HEVC, |
| 138 | AMEDIAFORMAT_KEY_THUMBNAIL_CSD_AV1C, |
| 139 | AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA, |
| 140 | AMEDIAFORMAT_KEY_SEI, |
| 141 | AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP, |
| 142 | AMEDIAFORMAT_KEY_PSSH, |
| 143 | AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS, |
| 144 | AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER, |
| 145 | AMEDIAFORMAT_KEY_MPEG_USER_DATA, |
| 146 | AMEDIAFORMAT_KEY_ICC_PROFILE, |
| 147 | AMEDIAFORMAT_KEY_HDR10_PLUS_INFO, |
| 148 | AMEDIAFORMAT_KEY_HDR_STATIC_INFO, |
| 149 | AMEDIAFORMAT_KEY_ESDS, |
| 150 | AMEDIAFORMAT_KEY_D263, |
| 151 | AMEDIAFORMAT_KEY_CSD_HEVC, |
| 152 | AMEDIAFORMAT_KEY_CSD_AVC, |
| 153 | AMEDIAFORMAT_KEY_CSD_2, |
| 154 | AMEDIAFORMAT_KEY_CSD_1, |
| 155 | AMEDIAFORMAT_KEY_CSD_0, |
| 156 | AMEDIAFORMAT_KEY_CSD, |
| 157 | AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, |
| 158 | AMEDIAFORMAT_KEY_CRYPTO_KEY, |
| 159 | AMEDIAFORMAT_KEY_CRYPTO_IV, |
| 160 | AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, |
| 161 | AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED, |
| 162 | AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, |
| 163 | AMEDIAFORMAT_KEY_ALBUMART, |
| 164 | }; |
| 165 | |
| 166 | static const std::string kFormatFloatKeys[] = {AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, |
| 167 | AMEDIAFORMAT_KEY_CAPTURE_RATE}; |
| 168 | |
| 169 | static const std::string kFormatStringKeys[] = {AMEDIAFORMAT_KEY_YEAR, |
| 170 | AMEDIAFORMAT_KEY_TITLE, |
| 171 | AMEDIAFORMAT_KEY_TEMPORAL_LAYERING, |
| 172 | AMEDIAFORMAT_KEY_SLOW_MOTION_MARKERS, |
| 173 | AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER, |
| 174 | AMEDIAFORMAT_KEY_MANUFACTURER, |
| 175 | AMEDIAFORMAT_KEY_LYRICIST, |
| 176 | AMEDIAFORMAT_KEY_LOCATION, |
| 177 | AMEDIAFORMAT_KEY_LANGUAGE, |
| 178 | AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE, |
| 179 | AMEDIAFORMAT_KEY_IS_AUTOSELECT, |
| 180 | AMEDIAFORMAT_KEY_IS_ADTS, |
| 181 | AMEDIAFORMAT_KEY_GENRE, |
| 182 | AMEDIAFORMAT_KEY_DISCNUMBER, |
| 183 | AMEDIAFORMAT_KEY_DATE, |
| 184 | AMEDIAFORMAT_KEY_COMPOSER, |
| 185 | AMEDIAFORMAT_KEY_COMPILATION, |
| 186 | AMEDIAFORMAT_KEY_COMPLEXITY, |
| 187 | AMEDIAFORMAT_KEY_CDTRACKNUMBER, |
| 188 | AMEDIAFORMAT_KEY_AUTHOR, |
| 189 | AMEDIAFORMAT_KEY_ARTIST, |
| 190 | AMEDIAFORMAT_KEY_ALBUMARTIST, |
| 191 | AMEDIAFORMAT_KEY_ALBUM}; |
| 192 | |
| 193 | void formatSetString(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) { |
| 194 | if (fdp->ConsumeBool()) { |
| 195 | std::string keyValue = fdp->ConsumeRandomLengthString(kMaxBytes); |
| 196 | AMediaFormat_setString(format, AMEDIAFORMAT_KEY, keyValue.c_str()); |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | void formatSetInt(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) { |
| 201 | if (fdp->ConsumeBool()) { |
| 202 | int32_t keyValue = fdp->ConsumeIntegralInRange<size_t>(kMinIntKeyValue, kMaxIntKeyValue); |
| 203 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY, keyValue); |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | void formatSetFloat(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) { |
| 208 | if (fdp->ConsumeBool()) { |
| 209 | float keyValue = |
| 210 | fdp->ConsumeFloatingPointInRange<float>(kMinFloatKeyValue, kMaxFloatKeyValue); |
| 211 | AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY, keyValue); |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | void formatSetBuffer(AMediaFormat* format, const char* AMEDIAFORMAT_KEY, FuzzedDataProvider* fdp) { |
| 216 | if (fdp->ConsumeBool()) { |
| 217 | std::vector<uint8_t> buffer = fdp->ConsumeBytes<uint8_t>( |
| 218 | fdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes)); |
| 219 | AMediaFormat_setBuffer(format, AMEDIAFORMAT_KEY, buffer.data(), buffer.size()); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByname(bool isEncoder, |
| 224 | bool isCodecForClient) { |
| 225 | std::string name; |
| 226 | if (isEncoder) { |
| 227 | name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kEncoderNames) |
| 228 | : mFdp->ConsumeRandomLengthString(kMaxBytes); |
| 229 | } else { |
| 230 | name = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kDecoderNames) |
| 231 | : mFdp->ConsumeRandomLengthString(kMaxBytes); |
| 232 | } |
| 233 | |
| 234 | if (isCodecForClient) { |
| 235 | pid_t pid = mFdp->ConsumeIntegral<pid_t>(); |
| 236 | uid_t uid = mFdp->ConsumeIntegral<uid_t>(); |
| 237 | return AMediaCodec_createCodecByNameForClient(name.c_str(), pid, uid); |
| 238 | |
| 239 | } else { |
| 240 | return AMediaCodec_createCodecByName(name.c_str()); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | AMediaCodec* NdkMediaCodecFuzzerBase::createAMediaCodecByType(bool isEncoder, |
| 245 | bool isCodecForClient) { |
| 246 | std::string mimeType; |
| 247 | const char* mime = nullptr; |
| 248 | |
| 249 | if (mFdp->ConsumeBool()) { |
| 250 | mimeType = mFdp->ConsumeRandomLengthString(kMaxBytes); |
| 251 | mime = mimeType.c_str(); |
| 252 | } else { |
| 253 | AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime); |
| 254 | } |
| 255 | |
| 256 | if (isCodecForClient) { |
| 257 | pid_t pid = mFdp->ConsumeIntegral<pid_t>(); |
| 258 | uid_t uid = mFdp->ConsumeIntegral<uid_t>(); |
| 259 | return isEncoder ? AMediaCodec_createEncoderByTypeForClient(mime, pid, uid) |
| 260 | : AMediaCodec_createDecoderByTypeForClient(mime, pid, uid); |
| 261 | } else { |
| 262 | return isEncoder ? AMediaCodec_createEncoderByType(mime) |
| 263 | : AMediaCodec_createDecoderByType(mime); |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | AMediaFormat* NdkMediaCodecFuzzerBase::getSampleCodecFormat() { |
| 268 | AMediaFormat* format = AMediaFormat_new(); |
| 269 | std::string value; |
| 270 | int32_t count = 0; |
| 271 | int32_t maxFormatKeys = 0; |
| 272 | |
| 273 | /*set mimeType*/ |
| 274 | if (mFdp->ConsumeBool()) { |
| 275 | value = mFdp->ConsumeRandomLengthString(kMaxBytes); |
| 276 | } else { |
| 277 | value = mFdp->PickValueInArray(kMimeTypes); |
| 278 | } |
| 279 | if (mFdp->ConsumeBool()) { |
| 280 | AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, value.c_str()); |
| 281 | } |
| 282 | |
| 283 | maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatStringKeys)); |
| 284 | for (count = 0; count < maxFormatKeys; ++count) { |
| 285 | std::string formatKey = mFdp->PickValueInArray(kFormatStringKeys); |
| 286 | formatSetString(format, formatKey.c_str(), mFdp); |
| 287 | } |
| 288 | |
| 289 | maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatIntKeys)); |
| 290 | for (count = 0; count < maxFormatKeys; ++count) { |
| 291 | std::string formatKey = mFdp->PickValueInArray(kFormatIntKeys); |
| 292 | formatSetInt(format, formatKey.c_str(), mFdp); |
| 293 | } |
| 294 | |
| 295 | maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatFloatKeys)); |
| 296 | for (count = 0; count < maxFormatKeys; ++count) { |
| 297 | std::string formatKey = mFdp->PickValueInArray(kFormatFloatKeys); |
| 298 | formatSetFloat(format, formatKey.c_str(), mFdp); |
| 299 | } |
| 300 | |
| 301 | maxFormatKeys = mFdp->ConsumeIntegralInRange<int32_t>(0, std::size(kFormatBufferKeys)); |
| 302 | for (count = 0; count < maxFormatKeys; ++count) { |
| 303 | std::string formatKey = mFdp->PickValueInArray(kFormatBufferKeys); |
| 304 | formatSetBuffer(format, formatKey.c_str(), mFdp); |
| 305 | } |
| 306 | return format; |
| 307 | } |
| 308 | |
| 309 | AMediaCodec* NdkMediaCodecFuzzerBase::createCodec(bool isEncoder, bool isCodecForClient) { |
| 310 | mFormat = getSampleCodecFormat(); |
| 311 | return (mFdp->ConsumeBool() ? createAMediaCodecByname(isEncoder, isCodecForClient) |
| 312 | : createAMediaCodecByType(isEncoder, isCodecForClient)); |
| 313 | } |
| 314 | |
| 315 | void NdkMediaCodecFuzzerBase::invokeCodecFormatAPI(AMediaCodec* codec) { |
| 316 | AMediaFormat* codecFormat = nullptr; |
| 317 | size_t codecFormatAPI = mFdp->ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxCodecFormatAPIs); |
| 318 | switch (codecFormatAPI) { |
| 319 | case 0: { |
| 320 | codecFormat = AMediaCodec_getInputFormat(codec); |
| 321 | break; |
| 322 | } |
| 323 | case 1: { |
| 324 | codecFormat = AMediaCodec_getOutputFormat(codec); |
| 325 | break; |
| 326 | } |
| 327 | case 2: |
| 328 | default: { |
| 329 | AMediaCodecBufferInfo info; |
| 330 | int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs); |
| 331 | ssize_t bufferIndex = 0; |
| 332 | if (mFdp->ConsumeBool()) { |
| 333 | bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs); |
| 334 | } else { |
| 335 | bufferIndex = |
| 336 | mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex); |
| 337 | } |
| 338 | codecFormat = AMediaCodec_getBufferFormat(codec, bufferIndex); |
| 339 | break; |
| 340 | } |
| 341 | } |
| 342 | if (codecFormat) { |
| 343 | AMediaFormat_delete(codecFormat); |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | void NdkMediaCodecFuzzerBase::invokeInputBufferOperationAPI(AMediaCodec* codec) { |
| 348 | size_t bufferSize = 0; |
| 349 | ssize_t bufferIndex = 0; |
| 350 | int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs); |
| 351 | if (mFdp->ConsumeBool()) { |
| 352 | bufferIndex = AMediaCodec_dequeueInputBuffer(codec, timeOutUs); |
| 353 | } else { |
| 354 | bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex); |
| 355 | } |
| 356 | |
| 357 | uint8_t* buffer = AMediaCodec_getInputBuffer(codec, bufferIndex, &bufferSize); |
| 358 | if (buffer) { |
| 359 | std::vector<uint8_t> bytesRead = mFdp->ConsumeBytes<uint8_t>( |
| 360 | std::min(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes), bufferSize)); |
| 361 | memcpy(buffer, bytesRead.data(), bytesRead.size()); |
| 362 | bufferSize = bytesRead.size(); |
| 363 | } |
| 364 | |
| 365 | int32_t flag = mFdp->ConsumeIntegralInRange<size_t>(AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG, |
| 366 | AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME); |
| 367 | if (mFdp->ConsumeBool()) { |
| 368 | AMediaCodec_queueInputBuffer(codec, bufferIndex, 0 /* offset */, bufferSize, 0 /* time */, |
| 369 | flag); |
| 370 | } else { |
| 371 | AMediaCodecCryptoInfo* cryptoInfo = getAMediaCodecCryptoInfo(); |
| 372 | AMediaCodec_queueSecureInputBuffer(codec, bufferIndex, 0 /* offset */, cryptoInfo, |
| 373 | 0 /* time */, flag); |
| 374 | AMediaCodecCryptoInfo_delete(cryptoInfo); |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | void NdkMediaCodecFuzzerBase::invokeOutputBufferOperationAPI(AMediaCodec* codec) { |
| 379 | ssize_t bufferIndex = 0; |
| 380 | int64_t timeOutUs = mFdp->ConsumeIntegralInRange<size_t>(kMinTimeOutUs, kMaxTimeOutUs); |
| 381 | if (mFdp->ConsumeBool()) { |
| 382 | AMediaCodecBufferInfo info; |
| 383 | bufferIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, timeOutUs); |
| 384 | } else { |
| 385 | bufferIndex = mFdp->ConsumeIntegralInRange<size_t>(kMinBufferIndex, kMaxBufferIndex); |
| 386 | } |
| 387 | |
| 388 | if (mFdp->ConsumeBool()) { |
| 389 | size_t bufferSize = 0; |
| 390 | (void)AMediaCodec_getOutputBuffer(codec, bufferIndex, &bufferSize); |
| 391 | } |
| 392 | |
| 393 | if (mFdp->ConsumeBool()) { |
| 394 | AMediaCodec_releaseOutputBuffer(codec, bufferIndex, mFdp->ConsumeBool()); |
| 395 | } else { |
| 396 | AMediaCodec_releaseOutputBufferAtTime(codec, bufferIndex, timeOutUs); |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | AMediaCodecCryptoInfo* NdkMediaCodecFuzzerBase::getAMediaCodecCryptoInfo() { |
| 401 | uint8_t key[kMaxCryptoKey]; |
| 402 | uint8_t iv[kMaxCryptoKey]; |
| 403 | size_t clearBytes[kMaxCryptoKey]; |
| 404 | size_t encryptedBytes[kMaxCryptoKey]; |
| 405 | |
| 406 | for (int32_t i = 0; i < kMaxCryptoKey; ++i) { |
| 407 | key[i] = mFdp->ConsumeIntegral<uint8_t>(); |
| 408 | iv[i] = mFdp->ConsumeIntegral<uint8_t>(); |
| 409 | clearBytes[i] = mFdp->ConsumeIntegral<size_t>(); |
| 410 | encryptedBytes[i] = mFdp->ConsumeIntegral<size_t>(); |
| 411 | } |
| 412 | |
| 413 | return AMediaCodecCryptoInfo_new(kMaxCryptoKey, key, iv, AMEDIACODECRYPTOINFO_MODE_CLEAR, |
| 414 | clearBytes, encryptedBytes); |
| 415 | } |