2017-01-02 207 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
较小的分配大小会导致堆损坏。