You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
457 lines
18 KiB
457 lines
18 KiB
/* |
|
* Copyright (c) 2012-2014, Linux Foundation. All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions are |
|
* met: |
|
* * Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* * Redistributions in binary form must reproduce the above |
|
* copyright notice, this list of conditions and the following |
|
* disclaimer in the documentation and/or other materials provided |
|
* with the distribution. |
|
* * Neither the name of Linux Foundation nor the names of its |
|
* contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
#ifndef LOG_TAG |
|
#define LOG_TAG "qsfdump" |
|
#endif |
|
#define LOG_NDEBUG 0 |
|
#include <hwc_utils.h> |
|
#include <hwc_dump_layers.h> |
|
#include <cutils/log.h> |
|
#include <sys/stat.h> |
|
#include <comptype.h> |
|
#ifdef QCOM_BSP |
|
// Ignore Wconversion errors for external headers |
|
#pragma GCC diagnostic push |
|
#pragma GCC diagnostic ignored "-Wconversion" |
|
#include <SkBitmap.h> |
|
#include <SkImageEncoder.h> |
|
#pragma GCC diagnostic pop |
|
#endif |
|
#ifdef STDC_FORMAT_MACROS |
|
#include <inttypes.h> |
|
#endif |
|
|
|
namespace qhwc { |
|
|
|
// MAX_ALLOWED_FRAMEDUMPS must be capped to (LONG_MAX - 1) |
|
// 60fps => 216000 frames per hour |
|
// Below setting of 216000 * 24 * 7 => 1 week or 168 hours of capture. |
|
enum { |
|
MAX_ALLOWED_FRAMEDUMPS = (216000 * 24 * 7) |
|
}; |
|
|
|
bool HwcDebug::sDumpEnable = false; |
|
|
|
HwcDebug::HwcDebug(uint32_t dpy): |
|
mDumpCntLimRaw(0), |
|
mDumpCntrRaw(1), |
|
mDumpCntLimPng(0), |
|
mDumpCntrPng(1), |
|
mDpy(dpy) { |
|
char dumpPropStr[PROPERTY_VALUE_MAX]; |
|
if(mDpy) { |
|
strlcpy(mDisplayName, "external", sizeof(mDisplayName)); |
|
} else { |
|
strlcpy(mDisplayName, "primary", sizeof(mDisplayName)); |
|
} |
|
snprintf(mDumpPropKeyDisplayType, sizeof(mDumpPropKeyDisplayType), |
|
"debug.sf.dump.%s", (char *)mDisplayName); |
|
|
|
if ((property_get("debug.sf.dump.enable", dumpPropStr, NULL) > 0)) { |
|
if(!strncmp(dumpPropStr, "true", strlen("true"))) { |
|
sDumpEnable = true; |
|
} |
|
} |
|
} |
|
|
|
void HwcDebug::dumpLayers(hwc_display_contents_1_t* list) |
|
{ |
|
// Check need for dumping layers for debugging. |
|
if (UNLIKELY(sDumpEnable) && UNLIKELY(needToDumpLayers()) && LIKELY(list)) { |
|
logHwcProps(list->flags); |
|
for (size_t i = 0; i < list->numHwLayers; i++) { |
|
logLayer(i, list->hwLayers); |
|
dumpLayer(i, list->hwLayers); |
|
} |
|
} |
|
} |
|
|
|
bool HwcDebug::needToDumpLayers() |
|
{ |
|
bool bDumpLayer = false; |
|
char dumpPropStr[PROPERTY_VALUE_MAX]; |
|
// Enable primary dump and disable external dump by default. |
|
bool bDumpEnable = !mDpy; |
|
time_t timeNow; |
|
tm dumpTime; |
|
|
|
// Override the bDumpEnable based on the property value, if the property |
|
// is present in the build.prop file. |
|
if ((property_get(mDumpPropKeyDisplayType, dumpPropStr, NULL) > 0)) { |
|
if(!strncmp(dumpPropStr, "true", strlen("true"))) |
|
bDumpEnable = true; |
|
else |
|
bDumpEnable = false; |
|
} |
|
|
|
if (false == bDumpEnable) |
|
return false; |
|
|
|
time(&timeNow); |
|
localtime_r(&timeNow, &dumpTime); |
|
|
|
if ((property_get("debug.sf.dump.png", dumpPropStr, NULL) > 0) && |
|
(strncmp(dumpPropStr, mDumpPropStrPng, PROPERTY_VALUE_MAX - 1))) { |
|
// Strings exist & not equal implies it has changed, so trigger a dump |
|
strlcpy(mDumpPropStrPng, dumpPropStr, sizeof(mDumpPropStrPng)); |
|
mDumpCntLimPng = atoi(dumpPropStr); |
|
if (mDumpCntLimPng > MAX_ALLOWED_FRAMEDUMPS) { |
|
ALOGW("Warning: Using debug.sf.dump.png %d (= max)", |
|
MAX_ALLOWED_FRAMEDUMPS); |
|
mDumpCntLimPng = MAX_ALLOWED_FRAMEDUMPS; |
|
} |
|
mDumpCntLimPng = (mDumpCntLimPng < 0) ? 0: mDumpCntLimPng; |
|
if (mDumpCntLimPng) { |
|
snprintf(mDumpDirPng, sizeof(mDumpDirPng), |
|
"/data/sfdump.png.%04d.%02d.%02d.%02d.%02d.%02d", |
|
dumpTime.tm_year + 1900, dumpTime.tm_mon + 1, |
|
dumpTime.tm_mday, dumpTime.tm_hour, |
|
dumpTime.tm_min, dumpTime.tm_sec); |
|
if (0 == mkdir(mDumpDirPng, 0777)) |
|
mDumpCntrPng = 0; |
|
else { |
|
ALOGE("Error: %s. Failed to create sfdump directory: %s", |
|
strerror(errno), mDumpDirPng); |
|
mDumpCntrPng = mDumpCntLimPng + 1; |
|
} |
|
} |
|
} |
|
|
|
if (mDumpCntrPng <= mDumpCntLimPng) |
|
mDumpCntrPng++; |
|
|
|
if ((property_get("debug.sf.dump", dumpPropStr, NULL) > 0) && |
|
(strncmp(dumpPropStr, mDumpPropStrRaw, PROPERTY_VALUE_MAX - 1))) { |
|
// Strings exist & not equal implies it has changed, so trigger a dump |
|
strlcpy(mDumpPropStrRaw, dumpPropStr, sizeof(mDumpPropStrRaw)); |
|
mDumpCntLimRaw = atoi(dumpPropStr); |
|
if (mDumpCntLimRaw > MAX_ALLOWED_FRAMEDUMPS) { |
|
ALOGW("Warning: Using debug.sf.dump %d (= max)", |
|
MAX_ALLOWED_FRAMEDUMPS); |
|
mDumpCntLimRaw = MAX_ALLOWED_FRAMEDUMPS; |
|
} |
|
mDumpCntLimRaw = (mDumpCntLimRaw < 0) ? 0: mDumpCntLimRaw; |
|
if (mDumpCntLimRaw) { |
|
snprintf(mDumpDirRaw, sizeof(mDumpDirRaw), |
|
"/data/sfdump.raw.%04d.%02d.%02d.%02d.%02d.%02d", |
|
dumpTime.tm_year + 1900, dumpTime.tm_mon + 1, |
|
dumpTime.tm_mday, dumpTime.tm_hour, |
|
dumpTime.tm_min, dumpTime.tm_sec); |
|
if (0 == mkdir(mDumpDirRaw, 0777)) |
|
mDumpCntrRaw = 0; |
|
else { |
|
ALOGE("Error: %s. Failed to create sfdump directory: %s", |
|
strerror(errno), mDumpDirRaw); |
|
mDumpCntrRaw = mDumpCntLimRaw + 1; |
|
} |
|
} |
|
} |
|
|
|
if (mDumpCntrRaw <= mDumpCntLimRaw) |
|
mDumpCntrRaw++; |
|
|
|
bDumpLayer = (mDumpCntLimPng || mDumpCntLimRaw)? true : false; |
|
return bDumpLayer; |
|
} |
|
|
|
void HwcDebug::logHwcProps(uint32_t listFlags) |
|
{ |
|
static int hwcModuleCompType = -1; |
|
static int sMdpCompMaxLayers = 0; |
|
static String8 hwcModuleCompTypeLog(""); |
|
if (-1 == hwcModuleCompType) { |
|
// One time stuff |
|
char mdpCompPropStr[PROPERTY_VALUE_MAX]; |
|
if (property_get("debug.mdpcomp.maxlayer", mdpCompPropStr, NULL) > 0) { |
|
sMdpCompMaxLayers = atoi(mdpCompPropStr); |
|
} |
|
hwcModuleCompType = |
|
qdutils::QCCompositionType::getInstance().getCompositionType(); |
|
hwcModuleCompTypeLog.appendFormat("%s%s%s%s%s%s", |
|
// Is hwc module composition type now a bit-field?! |
|
(hwcModuleCompType == qdutils::COMPOSITION_TYPE_GPU)? |
|
"[GPU]": "", |
|
(hwcModuleCompType & qdutils::COMPOSITION_TYPE_MDP)? |
|
"[MDP]": "", |
|
(hwcModuleCompType & qdutils::COMPOSITION_TYPE_C2D)? |
|
"[C2D]": "", |
|
(hwcModuleCompType & qdutils::COMPOSITION_TYPE_CPU)? |
|
"[CPU]": "", |
|
(hwcModuleCompType & qdutils::COMPOSITION_TYPE_DYN)? |
|
"[DYN]": "", |
|
(hwcModuleCompType >= (qdutils::COMPOSITION_TYPE_DYN << 1))? |
|
"[???]": ""); |
|
} |
|
ALOGI("Display[%s] Layer[*] %s-HwcModuleCompType, %d-layer MdpComp %s", |
|
mDisplayName, hwcModuleCompTypeLog.string(), sMdpCompMaxLayers, |
|
(listFlags & HWC_GEOMETRY_CHANGED)? "[HwcList Geometry Changed]": ""); |
|
} |
|
|
|
void HwcDebug::logLayer(size_t layerIndex, hwc_layer_1_t hwLayers[]) |
|
{ |
|
if (NULL == hwLayers) { |
|
ALOGE("Display[%s] Layer[%zu] Error. No hwc layers to log.", |
|
mDisplayName, layerIndex); |
|
return; |
|
} |
|
|
|
hwc_layer_1_t *layer = &hwLayers[layerIndex]; |
|
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); |
|
hwc_rect_t displayFrame = layer->displayFrame; |
|
size_t numHwcRects = layer->visibleRegionScreen.numRects; |
|
hwc_rect_t const *hwcRects = layer->visibleRegionScreen.rects; |
|
private_handle_t *hnd = (private_handle_t *)layer->handle; |
|
|
|
char pixFormatStr[32] = "None"; |
|
String8 hwcVisRegsScrLog("[None]"); |
|
|
|
for (size_t i = 0 ; (hwcRects && (i < numHwcRects)); i++) { |
|
if (0 == i) |
|
hwcVisRegsScrLog.clear(); |
|
hwcVisRegsScrLog.appendFormat("[%dl, %dt, %dr, %db]", |
|
hwcRects[i].left, hwcRects[i].top, |
|
hwcRects[i].right, hwcRects[i].bottom); |
|
} |
|
|
|
if (hnd) |
|
getHalPixelFormatStr(hnd->format, pixFormatStr); |
|
|
|
// Log Line 1 |
|
ALOGI("Display[%s] Layer[%zu] SrcBuff[%dx%d] SrcCrop[%dl, %dt, %dr, %db] " |
|
"DispFrame[%dl, %dt, %dr, %db] VisRegsScr%s", mDisplayName, layerIndex, |
|
(hnd)? getWidth(hnd) : -1, (hnd)? getHeight(hnd) : -1, |
|
sourceCrop.left, sourceCrop.top, |
|
sourceCrop.right, sourceCrop.bottom, |
|
displayFrame.left, displayFrame.top, |
|
displayFrame.right, displayFrame.bottom, |
|
hwcVisRegsScrLog.string()); |
|
// Log Line 2 |
|
ALOGI("Display[%s] Layer[%zu] LayerCompType = %s, Format = %s, " |
|
"Orientation = %s, Flags = %s%s%s, Hints = %s%s%s, " |
|
"Blending = %s%s%s", mDisplayName, layerIndex, |
|
(layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer(GPU)": |
|
(layer->compositionType == HWC_OVERLAY)? "Overlay": |
|
(layer->compositionType == HWC_BACKGROUND)? "Background":"???", |
|
pixFormatStr, |
|
(layer->transform == 0)? "ROT_0": |
|
(layer->transform == HWC_TRANSFORM_FLIP_H)? "FLIP_H": |
|
(layer->transform == HWC_TRANSFORM_FLIP_V)? "FLIP_V": |
|
(layer->transform == HWC_TRANSFORM_ROT_90)? "ROT_90": |
|
"ROT_INVALID", |
|
(layer->flags)? "": "[None]", |
|
(layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"", |
|
(layer->flags & qhwc::HWC_MDPCOMP)? "[MDP Comp]":"", |
|
(layer->hints)? "":"[None]", |
|
(layer->hints & HWC_HINT_TRIPLE_BUFFER)? "[Triple Buffer]":"", |
|
(layer->hints & HWC_HINT_CLEAR_FB)? "[Clear FB]":"", |
|
(layer->blending == HWC_BLENDING_NONE)? "[None]":"", |
|
(layer->blending == HWC_BLENDING_PREMULT)? "[PreMult]":"", |
|
(layer->blending == HWC_BLENDING_COVERAGE)? "[Coverage]":""); |
|
} |
|
|
|
void HwcDebug::dumpLayer(size_t layerIndex, hwc_layer_1_t hwLayers[]) |
|
{ |
|
char dumpLogStrPng[128] = ""; |
|
char dumpLogStrRaw[128] = ""; |
|
bool needDumpPng = (mDumpCntrPng <= mDumpCntLimPng)? true:false; |
|
bool needDumpRaw = (mDumpCntrRaw <= mDumpCntLimRaw)? true:false; |
|
|
|
if (needDumpPng) { |
|
snprintf(dumpLogStrPng, sizeof(dumpLogStrPng), |
|
"[png-dump-frame: %03d of %03d]", mDumpCntrPng, |
|
mDumpCntLimPng); |
|
} |
|
if (needDumpRaw) { |
|
snprintf(dumpLogStrRaw, sizeof(dumpLogStrRaw), |
|
"[raw-dump-frame: %03d of %03d]", mDumpCntrRaw, |
|
mDumpCntLimRaw); |
|
} |
|
|
|
if (!(needDumpPng || needDumpRaw)) |
|
return; |
|
|
|
if (NULL == hwLayers) { |
|
ALOGE("Display[%s] Layer[%zu] %s%s Error: No hwc layers to dump.", |
|
mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng); |
|
return; |
|
} |
|
|
|
hwc_layer_1_t *layer = &hwLayers[layerIndex]; |
|
private_handle_t *hnd = (private_handle_t *)layer->handle; |
|
char pixFormatStr[32] = "None"; |
|
|
|
if (NULL == hnd) { |
|
ALOGI("Display[%s] Layer[%zu] %s%s Skipping dump: Bufferless layer.", |
|
mDisplayName, layerIndex, dumpLogStrRaw, dumpLogStrPng); |
|
return; |
|
} |
|
|
|
getHalPixelFormatStr(hnd->format, pixFormatStr); |
|
#ifdef QCOM_BSP |
|
if (needDumpPng && hnd->base) { |
|
bool bResult = false; |
|
char dumpFilename[PATH_MAX]; |
|
SkColorType tempSkBmpColor = kUnknown_SkColorType; |
|
snprintf(dumpFilename, sizeof(dumpFilename), |
|
"%s/sfdump%03d.layer%zu.%s.png", mDumpDirPng, |
|
mDumpCntrPng, layerIndex, mDisplayName); |
|
|
|
switch (hnd->format) { |
|
case HAL_PIXEL_FORMAT_RGBA_8888: |
|
case HAL_PIXEL_FORMAT_RGBX_8888: |
|
tempSkBmpColor = kRGBA_8888_SkColorType; |
|
break; |
|
case HAL_PIXEL_FORMAT_BGRA_8888: |
|
tempSkBmpColor = kBGRA_8888_SkColorType; |
|
break; |
|
case HAL_PIXEL_FORMAT_RGB_565: |
|
tempSkBmpColor = kRGB_565_SkColorType; |
|
break; |
|
case HAL_PIXEL_FORMAT_RGBA_5551: |
|
case HAL_PIXEL_FORMAT_RGBA_4444: |
|
case HAL_PIXEL_FORMAT_RGB_888: |
|
default: |
|
tempSkBmpColor = kUnknown_SkColorType; |
|
break; |
|
} |
|
if (kUnknown_SkColorType != tempSkBmpColor) { |
|
SkImageInfo info = SkImageInfo::Make(getWidth(hnd), getHeight(hnd), |
|
tempSkBmpColor, kIgnore_SkAlphaType); |
|
SkPixmap pixmap(info, (const void*)hnd->base, info.minRowBytes()); |
|
SkFILEWStream file(dumpFilename); |
|
bResult = SkEncodeImage(&file, pixmap, SkEncodedImageFormat::kPNG, 100); |
|
ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s", |
|
mDisplayName, layerIndex, dumpLogStrPng, |
|
dumpFilename, bResult ? "Success" : "Fail"); |
|
} else { |
|
ALOGI("Display[%s] Layer[%zu] %s Skipping dump: Unsupported layer" |
|
" format %s for png encoder", |
|
mDisplayName, layerIndex, dumpLogStrPng, pixFormatStr); |
|
} |
|
} |
|
#endif |
|
if (needDumpRaw && hnd->base) { |
|
char dumpFilename[PATH_MAX]; |
|
bool bResult = false; |
|
snprintf(dumpFilename, sizeof(dumpFilename), |
|
"%s/sfdump%03d.layer%zu.%dx%d.%s.%s.raw", |
|
mDumpDirRaw, mDumpCntrRaw, |
|
layerIndex, getWidth(hnd), getHeight(hnd), |
|
pixFormatStr, mDisplayName); |
|
FILE* fp = fopen(dumpFilename, "w+"); |
|
if (NULL != fp) { |
|
bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp); |
|
fclose(fp); |
|
} |
|
ALOGI("Display[%s] Layer[%zu] %s Dump to %s: %s", |
|
mDisplayName, layerIndex, dumpLogStrRaw, |
|
dumpFilename, bResult ? "Success" : "Fail"); |
|
} |
|
} |
|
|
|
void HwcDebug::getHalPixelFormatStr(int format, char pixFormatStr[]) |
|
{ |
|
if (!pixFormatStr) |
|
return; |
|
|
|
switch(format) { |
|
case HAL_PIXEL_FORMAT_RGBA_8888: |
|
strlcpy(pixFormatStr, "RGBA_8888", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RGBX_8888: |
|
strlcpy(pixFormatStr, "RGBX_8888", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RGB_888: |
|
strlcpy(pixFormatStr, "RGB_888", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RGB_565: |
|
strlcpy(pixFormatStr, "RGB_565", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_BGRA_8888: |
|
strlcpy(pixFormatStr, "BGRA_8888", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RGBA_5551: |
|
strlcpy(pixFormatStr, "RGBA_5551", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RGBA_4444: |
|
strlcpy(pixFormatStr, "RGBA_4444", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YV12: |
|
strlcpy(pixFormatStr, "YV12", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCbCr_422_SP: |
|
strlcpy(pixFormatStr, "YCbCr_422_SP_NV16", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCrCb_420_SP: |
|
strlcpy(pixFormatStr, "YCrCb_420_SP_NV21", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCbCr_422_I: |
|
strlcpy(pixFormatStr, "YCbCr_422_I_YUY2", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCrCb_422_I: |
|
strlcpy(pixFormatStr, "YCrCb_422_I_YVYU", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: |
|
strlcpy(pixFormatStr, "NV12_ENCODEABLE", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: |
|
strlcpy(pixFormatStr, "YCbCr_420_SP_TILED_TILE_4x2", |
|
sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCbCr_420_SP: |
|
strlcpy(pixFormatStr, "YCbCr_420_SP", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: |
|
strlcpy(pixFormatStr, "YCrCb_420_SP_ADRENO", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCrCb_422_SP: |
|
strlcpy(pixFormatStr, "YCrCb_422_SP", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_R_8: |
|
strlcpy(pixFormatStr, "R_8", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_RG_88: |
|
strlcpy(pixFormatStr, "RG_88", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_INTERLACE: |
|
strlcpy(pixFormatStr, "INTERLACE", sizeof(pixFormatStr)); |
|
break; |
|
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: |
|
strlcpy(pixFormatStr, "YCbCr_420_SP_VENUS", sizeof(pixFormatStr)); |
|
break; |
|
default: |
|
size_t len = sizeof(pixFormatStr); |
|
snprintf(pixFormatStr, len, "Unknown0x%X", format); |
|
break; |
|
} |
|
} |
|
|
|
} // namespace qhwc |
|
|
|
|