2017-01-02 227 views
0

我嘗試了下面的代碼來檢查英特爾IPP是用於調整大小/轉換圖像的速度有多快,但它在最後仍然在ippsFree(pSpec)上崩潰,我無法弄清楚爲什麼。英特爾IPP ippsFree()崩潰

#include <stdint.h> 
#include <memory> 
#include <Windows.h> 
#include <time.h> 

#include "ipp.h" 

int main(...) { 
    srand(time(NULL)); 

    int width = 640; 
    int height = 480; 
    int channels = 2; 
    IppiResizeYUV422Spec* pSpec; 
    IppiSize dstSize, srcSize; 
    IppiPoint dstOffset = { 0, 0 }; 
    srcSize.width = width; 
    srcSize.height = height; 
    dstSize.width = 2 * width; 
    dstSize.height = 2 * height; 
    std::unique_ptr<unsigned char[]> sourceData; 
    std::unique_ptr<unsigned char[]> destinationData; 
    std::unique_ptr<unsigned char[]> destinationDataRGB; 
    std::unique_ptr<unsigned char[]> workBuffer; 

    sourceData.reset(new unsigned char[srcSize.width * srcSize.height * channels]); 
    destinationData.reset(new unsigned char[dstSize.width * dstSize.height * channels]); 
    destinationDataRGB.reset(new unsigned char[dstSize.width * dstSize.height * 3]); 
    workBuffer.reset(new unsigned char[dstSize.width * dstSize.height * channels]); 

    memset(sourceData.get(), 0, srcSize.width * srcSize.height * channels); 
    memset(destinationData.get(), 0, dstSize.width * dstSize.height * channels); 
    memset(workBuffer.get(), 0, dstSize.width * dstSize.height * channels); 

    IppStatus error; 
    int specSize = 0, initSize = 0, buffSize = 0; 
    error = ippiResizeGetSize_8u(srcSize, dstSize, IppiInterpolationType::ippNearest, 0, &specSize, &initSize); 

    pSpec = (IppiResizeYUV422Spec*) ippsMalloc_8u(specSize); 
    error = ippiResizeYUV422NearestInit(srcSize, dstSize, pSpec); 

    IppiRect srcRoi = { 0, 0, srcSize.width, srcSize.height }; 

    int64_t timerIPP9 = 0; 
    LARGE_INTEGER start, end; 
    LARGE_INTEGER tps; 
    QueryPerformanceFrequency(&tps); 

    for (unsigned int index = 0; index < 100; ++index) { 
     for (unsigned int imageIdx = 0; imageIdx < srcSize.width * srcSize.height * channels; ++imageIdx) { 
      sourceData.get()[imageIdx] = (rand() & 0xFF); 
     } 

     QueryPerformanceCounter(&start); 
     error = ippiResizeYUV422Nearest_8u_C2R(
      sourceData.get(), 
      srcSize.width * channels, 
      destinationData.get(), 
      dstSize.width * channels, 
      dstOffset, 
      dstSize, 
      pSpec, 
      workBuffer.get()); 
     QueryPerformanceCounter(&end); 

     timerIPP9 += end.QuadPart - start.QuadPart; 

     QueryPerformanceCounter(&start); 
     ippiYCbCr422ToRGB_8u_C2C3R(destinationData.get(), dstSize.width * channels, destinationDataRGB.get(), dstSize.width * 3, dstSize); 
     QueryPerformanceCounter(&end); 

     timerIPP9 += end.QuadPart - start.QuadPart; 
     printf("Test: %d, time: %d ms\r", index, timerIPP9 * 1000/tps.QuadPart); 
    } 

    ippsFree(pSpec); 
    printf("\n"); 
    printf("Time taken: %d ms\n", timerIPP9 * 1000/tps.QuadPart); 
    system("Pause"); 
    return 0; 
} 

我只是管道隨機數據到轉換器,但它應該能夠處理噪聲(因爲它仍然是一個有效的圖像)。

+0

我正在使用最新的英特爾IPP 2017.1.143 – SinisterMJ

+0

您是否嘗試過在分配後釋放權?它看起來並不像你在檢查錯誤響應。 (免責聲明:我從未使用過英特爾IPP) – owacoder

+0

我從來沒有使用過英特爾IPP。問題可能是你以某種方式寫在'pSpec'緩衝區之外,然後它在調用'ippsFree'時注意到? – gurka

回答

1

我想我解決了這個難題...

所有你需要做的是更換以下類似的代碼:

error = ippiResizeGetSize_8u(srcSize, dstSize, IppiInterpolationType::ippNearest, 0, &specSize, &initSize); 

用下面的一個:

error = ippiResizeYUV422GetSize(srcSize, dstSize, IppiInterpolationType::ippNearest, 0, &specSize, &initSize); 

根據到IPP文檔:

說明 此函數使用最近鄰居插值方法爲resize算法初始化IppiResizeYUV422Spec結構。
要計算spec結構對象的大小,請調用ippiResizeYUV422GetSize函數。

參見:http://hpc.ipp.ac.cn/wp-content/uploads/2015/12/documentation_2016/en/ipp/common/ipp_manual/GUID-15B51AB0-7F73-4E13-AC81-753259CE0E2C.htm

當執行ippiResizeYUV422GetSize,的specSize值等於11776
當執行ippiResizeGetSize_8u時,specSize的值等於9240
較小的分配大小會導致堆損壞。