interface clean and inside modification
clean and comment some API. move the SKIP mv pred location remove the unused buffer in intra construction.
This commit is contained in:
@@ -94,6 +94,7 @@ class ISVCDecoder {
|
||||
|
||||
/*
|
||||
* src must be 4 byte aligned, recommend 16 byte aligned. the available src size must be multiple of 4.
|
||||
* this API does not work for now!! This is for future use to support non-I420 color format output.
|
||||
*/
|
||||
virtual DECODING_STATE DecodeFrameEx (const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
|
||||
@@ -91,10 +91,9 @@ typedef enum {
|
||||
ENCODER_OPTION_CURRENT_PATH
|
||||
} ENCODER_OPTION;
|
||||
|
||||
/* Option types introduced in SVC decoder application */
|
||||
/* Option types introduced in decoder application */
|
||||
typedef enum {
|
||||
DECODER_OPTION_DATAFORMAT = 0, /* Set color space of decoding output frame */
|
||||
DECODER_OPTION_TRUNCATED_MODE, /* Used in decoding bitstream of non integrated frame, only truncated working mode is supported by tune, so skip it */
|
||||
DECODER_OPTION_END_OF_STREAM, /* Indicate bitstream of the final frame to be decoded */
|
||||
DECODER_OPTION_VCL_NAL, //feedback whether or not have VCL NAL in current AU for application layer
|
||||
DECODER_OPTION_TEMPORAL_ID, //feedback temporal id for application layer
|
||||
|
||||
@@ -71,10 +71,17 @@ void_t UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A
|
||||
int8_t iRefIndex[LIST_A][30],
|
||||
int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]);
|
||||
|
||||
/*!
|
||||
* \brief get the motion predictor for skip mode
|
||||
* \param
|
||||
* \param output iMvp[]
|
||||
*/
|
||||
void_t PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]);
|
||||
|
||||
/*!
|
||||
* \brief get the motion predictor for 4*4 or 8*8 or 16*16 block
|
||||
* \param
|
||||
* \param output mvp_x and mvp_y
|
||||
* \param output iMvp[]
|
||||
*/
|
||||
void_t PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
|
||||
int32_t iPartIdx, int32_t iPartWidth, int8_t iRef, int16_t iMVP[2]);
|
||||
|
||||
@@ -143,7 +143,6 @@ void_t WelsFillCacheConstrain1Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZe
|
||||
void_t WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer);
|
||||
|
||||
void_t PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]);
|
||||
|
||||
/*!
|
||||
* \brief check iPredMode for intra16x16 eligible or not
|
||||
|
||||
@@ -155,14 +155,6 @@ SI_SLICE = 4,
|
||||
UNKNOWN_SLICE = 5
|
||||
} ESliceType;
|
||||
|
||||
/* Slice Types in scalable extension */
|
||||
typedef uint8_t SliceTypeExt;
|
||||
enum {
|
||||
EP_SLICE = 0, // EP_SLICE: 0, 5
|
||||
EB_SLICE = 1, // EB_SLICE: 1, 6
|
||||
EI_SLICE = 2 // EI_SLICE: 2, 7
|
||||
};
|
||||
|
||||
/* List Index */
|
||||
typedef uint8_t ListIndex;
|
||||
enum {
|
||||
|
||||
@@ -247,27 +247,17 @@ int32_t WelsMbIntraPredictionConstruction (PWelsDecoderContext pCtx, PDqLayer pC
|
||||
//seems IPCM should not enter this path
|
||||
int32_t iMbXy = pCurLayer->iMbXyIndex;
|
||||
|
||||
FORCE_STACK_ALIGN_1D (int16_t, pTempScaledTCoeff, MB_COEFF_LIST_SIZE, 16);
|
||||
|
||||
memcpy (pTempScaledTCoeff, pCurLayer->pScaledTCoeff[iMbXy], 384 * sizeof (pCurLayer->pScaledTCoeff[iMbXy][0]));
|
||||
|
||||
WelsFillRecNeededMbInfo (pCtx, bOutput, pCurLayer);
|
||||
|
||||
if (IS_INTRA16x16 (pCurLayer->pMbType[iMbXy])) {
|
||||
int32_t i, j;
|
||||
// really need?
|
||||
for (i = 0; i < 16; i++) {
|
||||
j = g_kuiLumaDcZigzagScan[i];
|
||||
pTempScaledTCoeff[j] = pCurLayer->pScaledTCoeff[iMbXy][j];
|
||||
}
|
||||
WelsLumaDcDequantIdct (pTempScaledTCoeff, pCurLayer->pLumaQp[iMbXy]);
|
||||
RecI16x16Mb (iMbXy, pCtx, pTempScaledTCoeff, pCurLayer);
|
||||
WelsLumaDcDequantIdct (pCurLayer->pScaledTCoeff[iMbXy], pCurLayer->pLumaQp[iMbXy]);
|
||||
RecI16x16Mb (iMbXy, pCtx, pCurLayer->pScaledTCoeff[iMbXy], pCurLayer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_INTRA4x4 (pCurLayer->pMbType[iMbXy]))
|
||||
RecI4x4Mb (iMbXy, pCtx, pTempScaledTCoeff, pCurLayer);
|
||||
RecI4x4Mb (iMbXy, pCtx, pCurLayer->pScaledTCoeff[iMbXy], pCurLayer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -628,17 +628,6 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
pSliceHead->uiRefCount[1] = pPps->uiNumRefIdxL1Active;
|
||||
if (kbExtensionFlag) {
|
||||
uiQualityId = pNalHeaderExt->uiQualityId;
|
||||
if (BASE_QUALITY_ID == uiQualityId && (EP_SLICE == uiSliceType || EB_SLICE == uiSliceType)) {
|
||||
const bool_t kbBipredFlag = (EB_SLICE == uiSliceType);
|
||||
if (kbBipredFlag) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): kbBipredFlag = 1 not supported.\n");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_BIPRED);
|
||||
}
|
||||
pSliceHead->bNumRefIdxActiveOverrideFlag = !!BsGetOneBit (pBs);
|
||||
if (pSliceHead->bNumRefIdxActiveOverrideFlag) {
|
||||
pSliceHead->uiRefCount[0] = 1 + BsGetUe (pBs);
|
||||
}
|
||||
}
|
||||
} else if (uiSliceType == P_SLICE || uiSliceType == SP_SLICE || uiSliceType == B_SLICE) {
|
||||
const bool_t kbBipredFlag = (B_SLICE == uiSliceType);
|
||||
if (kbBipredFlag) {
|
||||
|
||||
@@ -43,6 +43,155 @@
|
||||
#include "mb_cache.h"
|
||||
|
||||
namespace WelsDec {
|
||||
void_t PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
|
||||
bool_t bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
|
||||
|
||||
int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
|
||||
int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
|
||||
int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy;
|
||||
|
||||
int8_t iLeftRef;
|
||||
int8_t iTopRef;
|
||||
int8_t iRightTopRef;
|
||||
int8_t iLeftTopRef;
|
||||
int8_t iDiagonalRef;
|
||||
int8_t iMatchRef;
|
||||
int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
|
||||
|
||||
iCurXy = pCurLayer->iMbXyIndex;
|
||||
iCurX = pCurLayer->iMbX;
|
||||
iCurY = pCurLayer->iMbY;
|
||||
iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
|
||||
|
||||
if (iCurX != 0) {
|
||||
iLeftXy = iCurXy - 1;
|
||||
iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
|
||||
bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bLeftAvail = 0;
|
||||
bLeftTopAvail = 0;
|
||||
}
|
||||
|
||||
if (iCurY != 0) {
|
||||
iTopXy = iCurXy - pCurLayer->iMbWidth;
|
||||
iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
|
||||
bTopAvail = (iTopSliceIdc == iCurSliceIdc);
|
||||
if (iCurX != 0) {
|
||||
iLeftTopXy = iTopXy - 1;
|
||||
iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
|
||||
bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bLeftTopAvail = 0;
|
||||
}
|
||||
if (iCurX != (pCurLayer->iMbWidth - 1)) {
|
||||
iRightTopXy = iTopXy + 1;
|
||||
iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
|
||||
bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bRightTopAvail = 0;
|
||||
}
|
||||
} else {
|
||||
bTopAvail = 0;
|
||||
bLeftTopAvail = 0;
|
||||
bRightTopAvail = 0;
|
||||
}
|
||||
|
||||
iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
|
||||
iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
|
||||
iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
|
||||
? pCurLayer->pMbType[iLeftTopXy] : 0);
|
||||
iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
|
||||
? pCurLayer->pMbType[iRightTopXy] : 0);
|
||||
|
||||
/*get neb mv&iRefIdxArray*/
|
||||
/*left*/
|
||||
if (bLeftAvail && IS_INTER (iLeftType)) {
|
||||
ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
|
||||
iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
|
||||
} else {
|
||||
ST32 (iMvA, 0);
|
||||
if (0 == bLeftAvail) { //not available
|
||||
iLeftRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iLeftRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
if (REF_NOT_AVAIL == iLeftRef ||
|
||||
(0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
|
||||
ST32 (iMvp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*top*/
|
||||
if (bTopAvail && IS_INTER (iTopType)) {
|
||||
ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
|
||||
iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
|
||||
} else {
|
||||
ST32 (iMvB, 0);
|
||||
if (0 == bTopAvail) { //not available
|
||||
iTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
if (REF_NOT_AVAIL == iTopRef ||
|
||||
(0 == iTopRef && 0 == * (int32_t*)iMvB)) {
|
||||
ST32 (iMvp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*right_top*/
|
||||
if (bRightTopAvail && IS_INTER (iRightTopType)) {
|
||||
ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
|
||||
iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
|
||||
} else {
|
||||
ST32 (iMvC, 0);
|
||||
if (0 == bRightTopAvail) { //not available
|
||||
iRightTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRightTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
/*left_top*/
|
||||
if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
|
||||
ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
|
||||
iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
|
||||
} else {
|
||||
ST32 (iMvD, 0);
|
||||
if (0 == bLeftTopAvail) { //not available
|
||||
iLeftTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iLeftTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
iDiagonalRef = iRightTopRef;
|
||||
if (REF_NOT_AVAIL == iDiagonalRef) {
|
||||
iDiagonalRef = iLeftTopRef;
|
||||
* (int32_t*)iMvC = * (int32_t*)iMvD;
|
||||
}
|
||||
|
||||
if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
|
||||
ST32 (iMvp, LD32 (iMvA));
|
||||
return;
|
||||
}
|
||||
|
||||
iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
|
||||
if (1 == iMatchRef) {
|
||||
if (0 == iLeftRef) {
|
||||
ST32 (iMvp, LD32 (iMvA));
|
||||
} else if (0 == iTopRef) {
|
||||
ST32 (iMvp, LD32 (iMvB));
|
||||
} else {
|
||||
ST32 (iMvp, LD32 (iMvC));
|
||||
}
|
||||
} else {
|
||||
iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
|
||||
iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//basic iMVs prediction unit for iMVs partition width (4, 2, 1)
|
||||
void_t PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
|
||||
|
||||
@@ -52,155 +52,6 @@
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
void_t PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
|
||||
bool_t bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
|
||||
|
||||
int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
|
||||
int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
|
||||
int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy;
|
||||
|
||||
int8_t iLeftRef;
|
||||
int8_t iTopRef;
|
||||
int8_t iRightTopRef;
|
||||
int8_t iLeftTopRef;
|
||||
int8_t iDiagonalRef;
|
||||
int8_t iMatchRef;
|
||||
int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
|
||||
|
||||
iCurXy = pCurLayer->iMbXyIndex;
|
||||
iCurX = pCurLayer->iMbX;
|
||||
iCurY = pCurLayer->iMbY;
|
||||
iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
|
||||
|
||||
if (iCurX != 0) {
|
||||
iLeftXy = iCurXy - 1;
|
||||
iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
|
||||
bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bLeftAvail = 0;
|
||||
bLeftTopAvail = 0;
|
||||
}
|
||||
|
||||
if (iCurY != 0) {
|
||||
iTopXy = iCurXy - pCurLayer->iMbWidth;
|
||||
iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
|
||||
bTopAvail = (iTopSliceIdc == iCurSliceIdc);
|
||||
if (iCurX != 0) {
|
||||
iLeftTopXy = iTopXy - 1;
|
||||
iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
|
||||
bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bLeftTopAvail = 0;
|
||||
}
|
||||
if (iCurX != (pCurLayer->iMbWidth - 1)) {
|
||||
iRightTopXy = iTopXy + 1;
|
||||
iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
|
||||
bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
|
||||
} else {
|
||||
bRightTopAvail = 0;
|
||||
}
|
||||
} else {
|
||||
bTopAvail = 0;
|
||||
bLeftTopAvail = 0;
|
||||
bRightTopAvail = 0;
|
||||
}
|
||||
|
||||
iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
|
||||
iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
|
||||
iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
|
||||
? pCurLayer->pMbType[iLeftTopXy] : 0);
|
||||
iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
|
||||
? pCurLayer->pMbType[iRightTopXy] : 0);
|
||||
|
||||
/*get neb mv&iRefIdxArray*/
|
||||
/*left*/
|
||||
if (bLeftAvail && IS_INTER (iLeftType)) {
|
||||
ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
|
||||
iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
|
||||
} else {
|
||||
ST32 (iMvA, 0);
|
||||
if (0 == bLeftAvail) { //not available
|
||||
iLeftRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iLeftRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
if (REF_NOT_AVAIL == iLeftRef ||
|
||||
(0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
|
||||
ST32 (iMvp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*top*/
|
||||
if (bTopAvail && IS_INTER (iTopType)) {
|
||||
ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
|
||||
iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
|
||||
} else {
|
||||
ST32 (iMvB, 0);
|
||||
if (0 == bTopAvail) { //not available
|
||||
iTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
if (REF_NOT_AVAIL == iTopRef ||
|
||||
(0 == iTopRef && 0 == * (int32_t*)iMvB)) {
|
||||
ST32 (iMvp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*right_top*/
|
||||
if (bRightTopAvail && IS_INTER (iRightTopType)) {
|
||||
ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
|
||||
iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
|
||||
} else {
|
||||
ST32 (iMvC, 0);
|
||||
if (0 == bRightTopAvail) { //not available
|
||||
iRightTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRightTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
/*left_top*/
|
||||
if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
|
||||
ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
|
||||
iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
|
||||
} else {
|
||||
ST32 (iMvD, 0);
|
||||
if (0 == bLeftTopAvail) { //not available
|
||||
iLeftTopRef = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iLeftTopRef = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
iDiagonalRef = iRightTopRef;
|
||||
if (REF_NOT_AVAIL == iDiagonalRef) {
|
||||
iDiagonalRef = iLeftTopRef;
|
||||
* (int32_t*)iMvC = * (int32_t*)iMvD;
|
||||
}
|
||||
|
||||
if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
|
||||
ST32 (iMvp, LD32 (iMvA));
|
||||
return;
|
||||
}
|
||||
|
||||
iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
|
||||
if (1 == iMatchRef) {
|
||||
if (0 == iLeftRef) {
|
||||
ST32 (iMvp, LD32 (iMvA));
|
||||
} else if (0 == iTopRef) {
|
||||
ST32 (iMvp, LD32 (iMvB));
|
||||
} else {
|
||||
ST32 (iMvp, LD32 (iMvC));
|
||||
}
|
||||
} else {
|
||||
iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
|
||||
iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void_t GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
|
||||
int32_t iCurXy, iTopXy, iLeftXy, iLeftTopXy, iRightTopXy;
|
||||
|
||||
Reference in New Issue
Block a user