1458 lines · 58.8 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2013, Cisco Systems *     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. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER 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. * */ #include "wels_preprocess.h"#include "picture_handle.h"#include "encoder_context.h"#include "utils.h"#include "encoder.h" namespace { void ClearEndOfLinePadding (uint8_t* pData, int32_t iStride, int32_t iWidth, int32_t iHeight) {  if (iWidth < iStride) {    for (int32_t i = 0; i < iHeight; ++i)      memset (pData + i * iStride + iWidth, 0, iStride - iWidth);  }} } // anon ns. namespace WelsEnc {   //***** entry API declaration ************************************************************************// int32_t WelsInitScaledPic (SWelsSvcCodingParam* pParam,  Scaled_Picture*  pScaledPic, CMemoryAlign* pMemoryAlign);bool  JudgeNeedOfScaling (SWelsSvcCodingParam* pParam, Scaled_Picture* pScaledPic);void    FreeScaledPic (Scaled_Picture*  pScaledPic, CMemoryAlign* pMemoryAlign);void  WelsMoveMemory_c (uint8_t* pDstY, uint8_t* pDstU, uint8_t* pDstV,  int32_t iDstStrideY, int32_t iDstStrideUV,                        uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iSrcStrideY, int32_t iSrcStrideUV, int32_t iWidth,                        int32_t iHeight); //******* table definition ***********************************************************************//const uint8_t g_kuiRefTemporalIdx[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE] = {  {  0, }, // 0  {  0,  0, }, // 1  {  0,  0,  0,  1, }, // 2  {  0,  0,  0,  2,  0,  1,  1,  2, }, // 3}; const int32_t g_kiPixMapSizeInBits = sizeof (uint8_t) * 8;  inline  void   WelsUpdateSpatialIdxMap (sWelsEncCtx* pEncCtx, const int32_t iPos, SPicture* const pPic,                                        const int32_t iDidx) {  pEncCtx->sSpatialIndexMap[iPos].pSrc = pPic;  pEncCtx->sSpatialIndexMap[iPos].iDid = iDidx;}  /*****************************************************************************   implement of the interface****************************************************************************/   CWelsPreProcess* CWelsPreProcess::CreatePreProcess (sWelsEncCtx* pEncCtx) {   CWelsPreProcess* pPreProcess = NULL;  switch (pEncCtx->pSvcParam->iUsageType) {  case SCREEN_CONTENT_REAL_TIME:    pPreProcess = WELS_NEW_OP (CWelsPreProcessScreen (pEncCtx),                               CWelsPreProcessScreen);    break;  default:    pPreProcess = WELS_NEW_OP (CWelsPreProcessVideo (pEncCtx),                               CWelsPreProcessVideo);    break;   }  WELS_VERIFY_RETURN_IF (NULL, NULL == pPreProcess)  return pPreProcess;}  CWelsPreProcess::CWelsPreProcess (sWelsEncCtx* pEncCtx) {  m_pInterfaceVp = NULL;  m_bInitDone = false;  m_pEncCtx = pEncCtx;  memset (&m_sScaledPicture, 0, sizeof (m_sScaledPicture));  memset (m_pSpatialPic, 0, sizeof (m_pSpatialPic));  memset (m_uiSpatialLayersInTemporal, 0, sizeof (m_uiSpatialLayersInTemporal));  memset (m_uiSpatialPicNum, 0, sizeof (m_uiSpatialPicNum));} CWelsPreProcess::~CWelsPreProcess() {  FreeScaledPic (&m_sScaledPicture,  m_pEncCtx->pMemAlign);  WelsPreprocessDestroy();} int32_t CWelsPreProcess::WelsPreprocessCreate() {  if (m_pInterfaceVp == NULL) {    WelsCreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);    if (!m_pInterfaceVp)      goto exit;  } else    goto exit;   return 0; exit:  WelsPreprocessDestroy();  return 1;} int32_t CWelsPreProcess::WelsPreprocessDestroy() {  WelsDestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);  m_pInterfaceVp = NULL;   return 0;} int32_t CWelsPreProcess::WelsPreprocessReset (sWelsEncCtx* pCtx, int32_t iWidth, int32_t iHeight) {  int32_t iRet = -1;  SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;  //init source width and height  pSvcParam->SUsedPicRect.iLeft = 0;  pSvcParam->SUsedPicRect.iTop  = 0;  pSvcParam->SUsedPicRect.iWidth =  iWidth;  pSvcParam->SUsedPicRect.iHeight = iHeight;  if ((iWidth < 16) || ((iHeight < 16))) {    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "Don't support width(%d) or height(%d) which is less than 16 ", iWidth,             iHeight);    return iRet;  }  if (pCtx) {    FreeScaledPic (&m_sScaledPicture, pCtx->pMemAlign);    iRet = InitLastSpatialPictures (pCtx);    iRet = WelsInitScaledPic (pCtx->pSvcParam, &m_sScaledPicture, pCtx->pMemAlign);  }   return iRet;} int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam) {  CMemoryAlign* pMa             = pCtx->pMemAlign;  const int32_t kiDlayerCount   = pParam->iSpatialLayerNum;  int32_t iDlayerIndex          = 0;   // spatial pictures  iDlayerIndex = 0;  do {    const int32_t kiPicWidth = pParam->sSpatialLayers[iDlayerIndex].iVideoWidth;    const int32_t kiPicHeight   = pParam->sSpatialLayers[iDlayerIndex].iVideoHeight;    const uint8_t kuiLayerInTemporal = 2 + WELS_MAX (pParam->sDependencyLayers[iDlayerIndex].iHighestTemporalId, 1);    const uint8_t kuiRefNumInTemporal = kuiLayerInTemporal + pParam->iLTRRefNum;    uint8_t i = 0;     m_uiSpatialPicNum[iDlayerIndex] = kuiRefNumInTemporal;    do {      SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false, 0);      WELS_VERIFY_RETURN_IF (1, (NULL == pPic))      m_pSpatialPic[iDlayerIndex][i] = pPic;      ++ i;    } while (i < kuiRefNumInTemporal);     if (pParam->iUsageType == SCREEN_CONTENT_REAL_TIME)      m_uiSpatialLayersInTemporal[iDlayerIndex] = 1;    else      m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal;     ++ iDlayerIndex;  } while (iDlayerIndex < kiDlayerCount);   return 0;} void CWelsPreProcess::FreeSpatialPictures (sWelsEncCtx* pCtx) {  CMemoryAlign* pMa = pCtx->pMemAlign;  int32_t j = 0;  while (j < pCtx->pSvcParam->iSpatialLayerNum) {    uint8_t i = 0;    uint8_t uiRefNumInTemporal = m_uiSpatialPicNum[j];     while (i < uiRefNumInTemporal) {      if (NULL != m_pSpatialPic[j][i]) {        FreePicture (pMa, &m_pSpatialPic[j][i]);      }      ++ i;    }    m_uiSpatialLayersInTemporal[j] = 0;    ++ j;  }} int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePicture* kpSrcPic) {  SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;  int32_t iSpatialNum = 0;  int32_t iWidth = ((kpSrcPic->iPicWidth >> 1) << 1);  int32_t iHeight = ((kpSrcPic->iPicHeight >> 1) << 1);   if (!m_bInitDone) {    if (WelsPreprocessCreate() != 0)      return -1;     if (WelsPreprocessReset (pCtx, iWidth, iHeight) != 0)      return -1;     m_iAvaliableRefInSpatialPicList = pSvcParam->iNumRefFrame;     m_bInitDone = true;  } else {    if ((iWidth != pSvcParam->SUsedPicRect.iWidth) || (iHeight != pSvcParam->SUsedPicRect.iHeight)) {      if (WelsPreprocessReset (pCtx, iWidth, iHeight) != 0)        return -1;    }  }   if (m_pInterfaceVp == NULL)    return -1;   pCtx->pVaa->bSceneChangeFlag = pCtx->pVaa->bIdrPeriodFlag = false;   iSpatialNum = SingleLayerPreprocess (pCtx, kpSrcPic, &m_sScaledPicture);   return iSpatialNum;} SPicture* CWelsPreProcess::GetBestRefPic (EUsageType iUsageType, bool bSceneLtr, EWelsSliceType eSliceType,    int32_t kiDidx, int32_t iRefTemporalIdx) {  assert (iUsageType == SCREEN_CONTENT_REAL_TIME);  SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);  SRefInfoParam* BestRefCandidateParam = (bSceneLtr) ? (& (pVaaExt->sVaaLtrBestRefCandidate[0])) :                                         (& (pVaaExt->sVaaStrBestRefCandidate[0]));  return m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx]; }SPicture* CWelsPreProcess::GetBestRefPic (const int32_t kiDidx, const int32_t iRefTemporalIdx) {   return m_pSpatialPic[kiDidx][iRefTemporalIdx];} int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiDidx) {  SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;  bool bNeededMbAq = (pSvcParam->bEnableAdaptiveQuant && (pCtx->eSliceType == P_SLICE));  bool bCalculateBGD = (pCtx->eSliceType == P_SLICE && pSvcParam->bEnableBackgroundDetection);  SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[kiDidx];  int32_t iCurTemporalIdx  = m_uiSpatialLayersInTemporal[kiDidx] - 1;   int32_t iRefTemporalIdx = (int32_t)g_kuiRefTemporalIdx[pSvcParam->iDecompStages][pParamInternal->iCodingIndex &                            (pSvcParam->uiGopSize - 1)];  if (pCtx->uiTemporalId == 0 && pCtx->pLtr[pCtx->uiDependencyId].bReceivedT0LostFlag)    iRefTemporalIdx = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiValidLongTermPicIdx;   SPicture* pCurPic = m_pSpatialPic[kiDidx][iCurTemporalIdx];  bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);   if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {    SPicture* pRefPic = GetBestRefPic (pSvcParam->iUsageType, pCtx->bCurFrameMarkedAsSceneLtr, pCtx->eSliceType, kiDidx,                                       iRefTemporalIdx);     VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD);     if (pSvcParam->bEnableBackgroundDetection) {      BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);    }    if (bNeededMbAq) {      AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);    }  } else {    SPicture* pRefPic = GetBestRefPic (kiDidx, iRefTemporalIdx);    SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];    bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);     VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, bCalculateSQDiff, bCalculateVar, bCalculateBGD);     if (pSvcParam->bEnableBackgroundDetection) {      BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);    }     if (bNeededMbAq) {      AdaptiveQuantCalculation (pCtx->pVaa, m_pLastSpatialPicture[kiDidx][1], m_pLastSpatialPicture[kiDidx][0]);    }  }  return 0;} int32_t CWelsPreProcess::GetCurPicPosition (const int32_t kiDidx) {  return (m_uiSpatialLayersInTemporal[kiDidx] - 1);} int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam,    const int8_t iCurTid, const int32_t kiDidx) {  if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)    return 0;   WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]);   const int32_t kiCurPos = GetCurPicPosition (kiDidx);  if (iCurTid < kiCurPos || pParam->iDecompStages == 0) {    if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (kiCurPos > MAX_TEMPORAL_LEVEL)) {      InitLastSpatialPictures (pCtx);      return 1;    }    if (pCtx->bRefOfCurTidIsLtr[kiDidx][iCurTid]) {      const int32_t kiAvailableLtrPos = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiMarkLongTermPicIdx;      WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiAvailableLtrPos],                                   &m_pSpatialPic[kiDidx][iCurTid]);      pCtx->bRefOfCurTidIsLtr[kiDidx][iCurTid] = false;    }    WelsExchangeSpatialPictures (&m_pSpatialPic[kiDidx][kiCurPos],                                 &m_pSpatialPic[kiDidx][iCurTid]);    }  return 0;}  /* *   SingleLayerPreprocess: down sampling if applicable *  @return: exact number of spatial layers need to encoder indeed */int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,    Scaled_Picture* pScaledPicture) {  SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;  int8_t  iDependencyId             = pSvcParam->iSpatialLayerNum - 1;   SPicture* pSrcPic                 = NULL; // large  SPicture* pDstPic                 = NULL; // small  SSpatialLayerConfig* pDlayerParam = NULL;  SSpatialLayerInternal* pDlayerParamInternal = NULL;  int32_t iSpatialNum               = 0;  int32_t iSrcWidth                 = 0;  int32_t iSrcHeight                = 0;  int32_t iTargetWidth              = 0;  int32_t iTargetHeight             = 0;  int32_t iTemporalId = 0;  int32_t iClosestDid =  iDependencyId;  pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];  pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];  iTargetWidth   = pDlayerParam->iVideoWidth;  iTargetHeight  = pDlayerParam->iVideoHeight;   iSrcWidth   = pSvcParam->SUsedPicRect.iWidth;  iSrcHeight  = pSvcParam->SUsedPicRect.iHeight;  if (pSvcParam->uiIntraPeriod) {    pCtx->pVaa->bIdrPeriodFlag = (1 + pDlayerParamInternal->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true :                                 false;    if (pCtx->pVaa->bIdrPeriodFlag) {      WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,           "pSvcParam->uiIntraPeriod=%d, pCtx->pVaa->bIdrPeriodFlag=%d",             pSvcParam->uiIntraPeriod,             pCtx->pVaa->bIdrPeriodFlag);    }  }   pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture : GetCurrentOrigFrame (              iDependencyId);   WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight);   if (pSvcParam->bEnableDenoise)    BilateralDenoising (pSrcPic, iSrcWidth, iSrcHeight);   // different scaling in between input picture and dst highest spatial picture.  int32_t iShrinkWidth  = iSrcWidth;  int32_t iShrinkHeight = iSrcHeight;  pDstPic = pSrcPic;  if (pScaledPicture->pScaledInputPicture) {    // for highest downsampling    pDstPic = GetCurrentOrigFrame (iDependencyId);    iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];    iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];  }  DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,                     false);   if (pSvcParam->bEnableSceneChangeDetect && !pCtx->pVaa->bIdrPeriodFlag) {    if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {      pCtx->pVaa->eSceneChangeIdc = (pDlayerParamInternal->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE :                                     DetectSceneChange (pDstPic));      pCtx->pVaa->bSceneChangeFlag = (LARGE_CHANGED_SCENE == pCtx->pVaa->eSceneChangeIdc);    } else {      if ((!pDlayerParamInternal->bEncCurFrmAsIdrFlag)          && ! (pDlayerParamInternal->iCodingIndex & (pSvcParam->uiGopSize - 1))) {        SPicture* pRefPic = pCtx->pLtr[iDependencyId].bReceivedT0LostFlag ?                            m_pSpatialPic[iDependencyId][m_uiSpatialLayersInTemporal[iDependencyId] +                                pCtx->pVaa->uiValidLongTermPicIdx] : m_pLastSpatialPicture[iDependencyId][0];        //pCtx->pVaa->eSceneChangeIdc = DetectSceneChange (pDstPic, pRefPic);        pCtx->pVaa->bSceneChangeFlag = GetSceneChangeFlag (DetectSceneChange (pDstPic, pRefPic));      }    }  }   for (int32_t i = 0; i < pSvcParam->iSpatialLayerNum; i++) {    pDlayerParamInternal = &pSvcParam->sDependencyLayers[i];    iTemporalId    = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                     (pSvcParam->uiGopSize - 1)];    if (iTemporalId != INVALID_TEMPORAL_ID) {      ++ iSpatialNum;    }  }  pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];  iTemporalId    = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                   (pSvcParam->uiGopSize - 1)];  int iActualSpatialNum = iSpatialNum - 1;  if (iTemporalId != INVALID_TEMPORAL_ID) {    WelsUpdateSpatialIdxMap (pCtx, iActualSpatialNum, pDstPic, iDependencyId);    -- iActualSpatialNum;  }   m_pLastSpatialPicture[iDependencyId][1] = GetCurrentOrigFrame (iDependencyId);  -- iDependencyId;    // generate other spacial layer  // pSrc is  //    -- padded input pic, if downsample should be applied to generate highest layer, [if] block above  //    -- highest layer, if no downsampling, [else] block above  if (pSvcParam->iSpatialLayerNum > 1) {    while (iDependencyId >= 0) {      pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];      pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];      SPicture* pSrcPic  = m_pLastSpatialPicture[iClosestDid][1]; // large      iTargetWidth  = pDlayerParam->iVideoWidth;      iTargetHeight = pDlayerParam->iVideoHeight;      iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &                    (pSvcParam->uiGopSize - 1)];       // down sampling performed      int32_t iSrcWidth                 = pScaledPicture->iScaledWidth[iClosestDid];      int32_t iSrcHeight                = pScaledPicture->iScaledHeight[iClosestDid];      pDstPic = GetCurrentOrigFrame (iDependencyId); // small      iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];      iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];      DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,                         true);       if ((iTemporalId != INVALID_TEMPORAL_ID)) {        WelsUpdateSpatialIdxMap (pCtx, iActualSpatialNum, pDstPic, iDependencyId);        iActualSpatialNum--;      }       m_pLastSpatialPicture[iDependencyId][1] = pDstPic;       iClosestDid = iDependencyId;      -- iDependencyId;     }  }  return iSpatialNum; }  /*! * \brief   Whether input picture need be scaled? */bool JudgeNeedOfScaling (SWelsSvcCodingParam* pParam, Scaled_Picture* pScaledPicture) {  const int32_t kiInputPicWidth  = pParam->SUsedPicRect.iWidth;  const int32_t kiInputPicHeight = pParam->SUsedPicRect.iHeight;  const int32_t kiDstPicWidth    = pParam->sDependencyLayers[pParam->iSpatialLayerNum - 1].iActualWidth;  const int32_t kiDstPicHeight   = pParam->sDependencyLayers[pParam->iSpatialLayerNum - 1].iActualHeight;  bool bNeedDownsampling = true;   int32_t iSpatialIdx = pParam->iSpatialLayerNum - 1;   if (kiDstPicWidth >= kiInputPicWidth && kiDstPicHeight >= kiInputPicHeight) {    bNeedDownsampling = false;  }   for (; iSpatialIdx >= 0; iSpatialIdx --) {    SSpatialLayerInternal* pCurLayer = &pParam->sDependencyLayers[iSpatialIdx];    int32_t iCurDstWidth             = pCurLayer->iActualWidth;    int32_t iCurDstHeight            = pCurLayer->iActualHeight;    int32_t iInputWidthXDstHeight    = kiInputPicWidth * iCurDstHeight;    int32_t iInputHeightXDstWidth    = kiInputPicHeight * iCurDstWidth;

Lines 1–500 of 1458.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t