Suyog Pawar | 4602c37 | 2023-08-17 11:09:23 +0530 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2023 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 | //#define LOG_NDEBUG 0 |
| 17 | #define LOG_TAG "C2SoftDav1dDump" |
| 18 | #include "C2SoftDav1dDump.h" |
| 19 | |
| 20 | namespace android { |
| 21 | |
| 22 | // Flag to enable dumping the bitsteram and the decoded pictures to files. |
| 23 | static const bool ENABLE_DUMPING_FILES_DEFAULT = true; |
| 24 | static const char ENABLE_DUMPING_FILES_PROPERTY[] = "debug.dav1d.enabledumping"; |
| 25 | |
| 26 | // The number of frames to dump to a file |
| 27 | static const int NUM_FRAMES_TO_DUMP_DEFAULT = INT_MAX; |
| 28 | static const char NUM_FRAMES_TO_DUMP_PROPERTY[] = "debug.dav1d.numframestodump"; |
| 29 | |
| 30 | // start dumping from this frame |
| 31 | static const int STARTING_FRAME_TO_DUMP_DEFAULT = 0; |
| 32 | static const char STARTING_FRAME_TO_DUMP_PROPERTY[] = "debug.dav1d.startingframetodump"; |
| 33 | |
| 34 | void C2SoftDav1dDump::initDumping() { |
| 35 | nsecs_t now = systemTime(); |
| 36 | snprintf(mInDataFileName, kFileNameLength, "%s_%" PRId64 "d.%s", DUMP_FILE_PATH, now, |
| 37 | INPUT_DATA_DUMP_EXT); |
| 38 | snprintf(mInSizeFileName, kFileNameLength, "%s_%" PRId64 "d.%s", DUMP_FILE_PATH, now, |
| 39 | INPUT_SIZE_DUMP_EXT); |
| 40 | snprintf(mDav1dOutYuvFileName, kFileNameLength, "%s_%" PRId64 "dx.%s", DUMP_FILE_PATH, now, |
| 41 | OUTPUT_YUV_DUMP_EXT); |
| 42 | |
| 43 | mFramesToDump = |
| 44 | android::base::GetIntProperty(NUM_FRAMES_TO_DUMP_PROPERTY, NUM_FRAMES_TO_DUMP_DEFAULT); |
| 45 | mFirstFrameToDump = android::base::GetIntProperty(STARTING_FRAME_TO_DUMP_PROPERTY, |
| 46 | STARTING_FRAME_TO_DUMP_DEFAULT); |
| 47 | bool enableDumping = android::base::GetBoolProperty(ENABLE_DUMPING_FILES_PROPERTY, |
| 48 | ENABLE_DUMPING_FILES_DEFAULT); |
| 49 | ALOGD("enableDumping = %d, mFramesToDump = %d", enableDumping, mFramesToDump); |
| 50 | |
| 51 | if (enableDumping) { |
| 52 | mInDataFile = fopen(mInDataFileName, "wb"); |
| 53 | if (mInDataFile == nullptr) { |
| 54 | ALOGD("Could not open file %s", mInDataFileName); |
| 55 | } |
| 56 | |
| 57 | mInSizeFile = fopen(mInSizeFileName, "wb"); |
| 58 | if (mInSizeFile == nullptr) { |
| 59 | ALOGD("Could not open file %s", mInSizeFileName); |
| 60 | } |
| 61 | |
| 62 | mDav1dOutYuvFile = fopen(mDav1dOutYuvFileName, "wb"); |
| 63 | if (mDav1dOutYuvFile == nullptr) { |
| 64 | ALOGD("Could not open file %s", mDav1dOutYuvFileName); |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | void C2SoftDav1dDump::destroyDumping() { |
| 70 | if (mInDataFile != nullptr) { |
| 71 | fclose(mInDataFile); |
| 72 | mInDataFile = nullptr; |
| 73 | } |
| 74 | |
| 75 | if (mInSizeFile != nullptr) { |
| 76 | fclose(mInSizeFile); |
| 77 | mInSizeFile = nullptr; |
| 78 | } |
| 79 | |
| 80 | if (mDav1dOutYuvFile != nullptr) { |
| 81 | fclose(mDav1dOutYuvFile); |
| 82 | mDav1dOutYuvFile = nullptr; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | void C2SoftDav1dDump::dumpInput(uint8_t* ptr, int size) { |
| 87 | if (mInDataFile) { |
| 88 | int ret = fwrite(ptr, 1, size, mInDataFile); |
| 89 | |
| 90 | if (ret != size) { |
| 91 | ALOGE("Error in fwrite %s, requested %d, returned %d", mInDataFileName, size, ret); |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | // Dump the size per inputBuffer if dumping is enabled. |
| 96 | if (mInSizeFile) { |
| 97 | int ret = fwrite(&size, 1, 4, mInSizeFile); |
| 98 | |
| 99 | if (ret != 4) { |
| 100 | ALOGE("Error in fwrite %s, requested %d, returned %d", mInSizeFileName, 4, ret); |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | template <typename T> |
| 106 | void C2SoftDav1dDump::dumpOutput(const T* srcY, const T* srcU, const T* srcV, size_t srcYStride, |
| 107 | size_t srcUStride, size_t srcVStride, int width, int height) { |
| 108 | mOutputCount++; |
| 109 | FILE* fp_out = mDav1dOutYuvFile; |
| 110 | int typeSize = sizeof(T); |
| 111 | if (fp_out && mOutputCount >= mFirstFrameToDump && |
| 112 | mOutputCount <= (mFirstFrameToDump + mFramesToDump - 1)) { |
| 113 | for (int i = 0; i < height; i++) { |
| 114 | int ret = |
| 115 | fwrite((uint8_t*)srcY + i * srcYStride * typeSize, 1, width * typeSize, fp_out); |
| 116 | if (ret != width * typeSize) { |
| 117 | ALOGE("Error in fwrite, requested %d, returned %d", width * typeSize, ret); |
| 118 | break; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | for (int i = 0; i < height / 2; i++) { |
| 123 | int ret = fwrite((uint8_t*)srcU + i * srcUStride * typeSize, 1, width * typeSize / 2, |
| 124 | fp_out); |
| 125 | if (ret != width * typeSize / 2) { |
| 126 | ALOGE("Error in fwrite, requested %d, returned %d", width * typeSize / 2, ret); |
| 127 | break; |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | for (int i = 0; i < height / 2; i++) { |
| 132 | int ret = fwrite((uint8_t*)srcV + i * srcVStride * typeSize, 1, width * typeSize / 2, |
| 133 | fp_out); |
| 134 | if (ret != width * typeSize / 2) { |
| 135 | ALOGE("Error in fwrite, requested %d, returned %d", width * typeSize / 2, ret); |
| 136 | break; |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | void C2SoftDav1dDump::writeDav1dOutYuvFile(const Dav1dPicture& p) { |
| 143 | if (mDav1dOutYuvFile != NULL) { |
| 144 | uint8_t* ptr; |
| 145 | const int hbd = p.p.bpc > 8; |
| 146 | |
| 147 | ptr = (uint8_t*)p.data[0]; |
| 148 | for (int y = 0; y < p.p.h; y++) { |
| 149 | int iSize = p.p.w << hbd; |
| 150 | int ret = fwrite(ptr, 1, iSize, mDav1dOutYuvFile); |
| 151 | if (ret != iSize) { |
| 152 | ALOGE("Error in fwrite %s, requested %d, returned %d", mDav1dOutYuvFileName, iSize, |
| 153 | ret); |
| 154 | break; |
| 155 | } |
| 156 | |
| 157 | ptr += p.stride[0]; |
| 158 | } |
| 159 | |
| 160 | if (p.p.layout != DAV1D_PIXEL_LAYOUT_I400) { |
| 161 | // u/v |
| 162 | const int ss_ver = p.p.layout == DAV1D_PIXEL_LAYOUT_I420; |
| 163 | const int ss_hor = p.p.layout != DAV1D_PIXEL_LAYOUT_I444; |
| 164 | const int cw = (p.p.w + ss_hor) >> ss_hor; |
| 165 | const int ch = (p.p.h + ss_ver) >> ss_ver; |
| 166 | for (int pl = 1; pl <= 2; pl++) { |
| 167 | ptr = (uint8_t*)p.data[pl]; |
| 168 | for (int y = 0; y < ch; y++) { |
| 169 | int iSize = cw << hbd; |
| 170 | int ret = fwrite(ptr, 1, cw << hbd, mDav1dOutYuvFile); |
| 171 | if (ret != iSize) { |
| 172 | ALOGE("Error in fwrite %s, requested %d, returned %d", mDav1dOutYuvFileName, |
| 173 | iSize, ret); |
| 174 | break; |
| 175 | } |
| 176 | ptr += p.stride[1]; |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | template void C2SoftDav1dDump::dumpOutput<uint8_t>(const uint8_t* srcY, const uint8_t* srcU, |
| 184 | const uint8_t* srcV, size_t srcYStride, |
| 185 | size_t srcUStride, size_t srcVStride, int width, |
| 186 | int height); |
| 187 | template void C2SoftDav1dDump::dumpOutput<uint16_t>(const uint16_t* srcY, const uint16_t* srcU, |
| 188 | const uint16_t* srcV, size_t srcYStride, |
| 189 | size_t srcUStride, size_t srcVStride, int width, |
| 190 | int height); |
| 191 | } // namespace android |