| // Copyright (C) 2020 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "host-common/H264PingInfoParser.h" |
| |
| #define H264_DEBUG 0 |
| |
| #if H264_DEBUG |
| #define RED "\x1B[31m" |
| #define GRN "\x1B[32m" |
| #define YEL "\x1B[33m" |
| #define BLU "\x1B[34m" |
| #define MAG "\x1B[35m" |
| #define CYN "\x1B[36m" |
| #define WHT "\x1B[37m" |
| #define RESET "\x1B[0m" |
| #define H264_PRINT(color, fmt, ...) \ |
| fprintf(stderr, color "H264PingInfoParser: %s:%d " fmt "\n" RESET, \ |
| __func__, __LINE__, ##__VA_ARGS__); |
| #else |
| #define H264_PRINT(fmt, ...) |
| #endif |
| |
| #define H264_INFO(fmt, ...) H264_PRINT(RESET, fmt, ##__VA_ARGS__); |
| #define H264_WARN(fmt, ...) H264_PRINT(YEL, fmt, ##__VA_ARGS__); |
| #define H264_ERROR(fmt, ...) H264_PRINT(RED, fmt, ##__VA_ARGS__); |
| |
| namespace android { |
| namespace emulation { |
| |
| H264PingInfoParser::H264PingInfoParser(void* ptr) { |
| mVersion = parseVersion(ptr); |
| } |
| |
| H264PingInfoParser::H264PingInfoParser(uint32_t version) { |
| mVersion = version; |
| } |
| |
| uint32_t H264PingInfoParser::parseVersion(void* ptr) { |
| uint8_t* xptr = (uint8_t*)ptr; |
| uint32_t version = *(uint32_t*)xptr; |
| return version; |
| } |
| |
| void H264PingInfoParser::parseInitContextParams(void* ptr, |
| InitContextParam& param) { |
| uint8_t* xptr = (uint8_t*)ptr; |
| param.version = *(uint32_t*)xptr; |
| param.width = *(unsigned int*)(xptr + 8); |
| param.height = *(unsigned int*)(xptr + 16); |
| param.outputWidth = *(unsigned int*)(xptr + 24); |
| param.outputHeight = *(unsigned int*)(xptr + 32); |
| param.outputPixelFormat = static_cast<PixelFormat>(*(uint8_t*)(xptr + 40)); |
| param.pHostDecoderId = static_cast<uint64_t*>(getReturnAddress(ptr)); |
| } |
| |
| uint64_t H264PingInfoParser::parseHostDecoderId(void* ptr) { |
| if (nullptr == ptr) |
| return 0; |
| uint64_t key = (*reinterpret_cast<uint64_t*>(ptr)); |
| return key; |
| } |
| |
| void H264PingInfoParser::parseDecodeFrameParams(void* ptr, |
| DecodeFrameParam& param) { |
| param.hostDecoderId = parseHostDecoderId(ptr); |
| uint64_t offset = *(uint64_t*)((uint8_t*)ptr + 8); |
| param.pData = (uint8_t*)ptr + offset; |
| param.size = *(size_t*)((uint8_t*)ptr + 16); |
| param.pts = *(size_t*)((uint8_t*)ptr + 24); |
| uint8_t* retptr = (uint8_t*)getReturnAddress(ptr); |
| param.pConsumedBytes = (size_t*)(retptr); |
| param.pDecoderErrorCode = (int*)(retptr + 8); |
| } |
| |
| void H264PingInfoParser::parseResetParams(void* ptr, ResetParam& param) { |
| uint8_t* xptr = (uint8_t*)ptr; |
| param.hostDecoderId = parseHostDecoderId(ptr); |
| param.width = *(unsigned int*)(xptr + 8); |
| param.height = *(unsigned int*)(xptr + 16); |
| param.outputWidth = *(unsigned int*)(xptr + 24); |
| param.outputHeight = *(unsigned int*)(xptr + 32); |
| param.outputPixelFormat = static_cast<PixelFormat>(*(uint8_t*)(xptr + 40)); |
| } |
| |
| int32_t H264PingInfoParser::parseHostColorBufferId(void* ptr) { |
| // Guest will pass us the hsot color buffer id to send decoded frame to |
| uint8_t* xptr = (uint8_t*)ptr; |
| int32_t colorBufferId = *(int32_t*)(xptr + 16); |
| return colorBufferId; |
| } |
| |
| void* H264PingInfoParser::getReturnAddress(void* ptr) { |
| uint8_t* xptr = (uint8_t*)ptr; |
| void* pint = (void*)(xptr + 256); |
| return pint; |
| } |
| |
| void H264PingInfoParser::parseGetImageParams(void* ptr, GetImageParam& param) { |
| param.hostDecoderId = parseHostDecoderId(ptr); |
| if (mVersion == 100) { |
| param.hostColorBufferId = -1; |
| } else if (mVersion == 200) { |
| param.hostColorBufferId = parseHostColorBufferId(ptr); |
| } |
| uint8_t* retptr = (uint8_t*)getReturnAddress(ptr); |
| param.pDecoderErrorCode = (int*)(retptr); |
| param.pRetWidth = (uint32_t*)(retptr + 8); |
| param.pRetHeight = (uint32_t*)(retptr + 16); |
| param.pRetPts = (uint64_t*)(retptr + 24); |
| param.pRetColorPrimaries = (uint32_t*)(retptr + 32); |
| param.pRetColorRange = (uint32_t*)(retptr + 40); |
| param.pRetColorTransfer = (uint32_t*)(retptr + 48); |
| param.pRetColorSpace = (uint32_t*)(retptr + 56); |
| |
| uint8_t* xptr = (uint8_t*)ptr; |
| uint64_t offset = *(uint64_t*)(xptr + 8); |
| param.pDecodedFrame = (uint8_t*)ptr + offset; |
| } |
| |
| } // namespace emulation |
| } // namespace android |