Apply consistent code formatting across the repo. Add clang-format and pre-commit hooks.

This commit is contained in:
Rob Armstrong
2025-03-27 10:30:07 -07:00
parent 2cd58fbc9a
commit ceab6e8bcc
782 changed files with 107230 additions and 106548 deletions

View File

@@ -30,38 +30,58 @@
#include <cuda.h>
#include <cuda_runtime.h>
#include "resize_convert.h"
__global__ void resizeBGRplanarBatchKernel(cudaTextureObject_t texSrc,
float *pDst, int nDstPitch, int nDstHeight, int nSrcHeight,
int batch, float scaleX, float scaleY,
int cropX, int cropY, int cropW, int cropH) {
float *pDst,
int nDstPitch,
int nDstHeight,
int nSrcHeight,
int batch,
float scaleX,
float scaleY,
int cropX,
int cropY,
int cropW,
int cropH)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
if (x >= (int)(cropW/scaleX) || y >= (int)(cropH/scaleY))
if (x >= (int)(cropW / scaleX) || y >= (int)(cropH / scaleY))
return;
int frameSize = nDstPitch*nDstHeight;
float *p = NULL;
int frameSize = nDstPitch * nDstHeight;
float *p = NULL;
for (int i = blockIdx.z; i < batch; i += gridDim.z) {
#pragma unroll
for (int channel=0; channel < 3; channel++){
p = pDst + i * 3 * frameSize + y * nDstPitch + x + channel * frameSize;
*p = tex2D<float>(texSrc, x * scaleX + cropX,
((3 * i + channel) * nSrcHeight + y * scaleY + cropY));
#pragma unroll
for (int channel = 0; channel < 3; channel++) {
p = pDst + i * 3 * frameSize + y * nDstPitch + x + channel * frameSize;
*p = tex2D<float>(texSrc, x * scaleX + cropX, ((3 * i + channel) * nSrcHeight + y * scaleY + cropY));
}
}
}
static void resizeBGRplanarBatchCore(
float *dpSrc, int nSrcPitch, int nSrcWidth, int nSrcHeight,
float *dpDst, int nDstPitch, int nDstWidth, int nDstHeight,
int nBatchSize, cudaStream_t stream, bool whSameResizeRatio,
int cropX, int cropY, int cropW, int cropH) {
static void resizeBGRplanarBatchCore(float *dpSrc,
int nSrcPitch,
int nSrcWidth,
int nSrcHeight,
float *dpDst,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize,
cudaStream_t stream,
bool whSameResizeRatio,
int cropX,
int cropY,
int cropW,
int cropH)
{
cudaTextureObject_t texSrc[2];
int nTiles = 1, h, iTile;
int nTiles = 1, h, iTile;
h = nSrcHeight * 3 * nBatchSize;
while ((h + nTiles - 1) / nTiles > 65536)
@@ -70,65 +90,85 @@ static void resizeBGRplanarBatchCore(
if (nTiles > 2)
return;
int batchTile = nBatchSize / nTiles;
int batchTileLast = nBatchSize - batchTile * (nTiles-1);
int batchTile = nBatchSize / nTiles;
int batchTileLast = nBatchSize - batchTile * (nTiles - 1);
for (iTile = 0; iTile < nTiles; ++iTile) {
int bs = (iTile == nTiles - 1) ? batchTileLast : batchTile;
float *dpSrcNew = dpSrc +
iTile * (batchTile * 3 * nSrcHeight * nSrcPitch);
int bs = (iTile == nTiles - 1) ? batchTileLast : batchTile;
float *dpSrcNew = dpSrc + iTile * (batchTile * 3 * nSrcHeight * nSrcPitch);
cudaResourceDesc resDesc = {};
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = dpSrcNew;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<float>();
resDesc.res.pitch2D.width = nSrcWidth;
resDesc.res.pitch2D.height = bs * 3 * nSrcHeight;
cudaResourceDesc resDesc = {};
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = dpSrcNew;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<float>();
resDesc.res.pitch2D.width = nSrcWidth;
resDesc.res.pitch2D.height = bs * 3 * nSrcHeight;
resDesc.res.pitch2D.pitchInBytes = nSrcPitch * sizeof(float);
cudaTextureDesc texDesc = {};
texDesc.filterMode = cudaFilterModeLinear;
texDesc.readMode = cudaReadModeElementType;
cudaTextureDesc texDesc = {};
texDesc.filterMode = cudaFilterModeLinear;
texDesc.readMode = cudaReadModeElementType;
checkCudaErrors(cudaCreateTextureObject(&texSrc[iTile], &resDesc, &texDesc, NULL));
float *dpDstNew = dpDst +
iTile * (batchTile * 3 * nDstHeight * nDstPitch);
float *dpDstNew = dpDst + iTile * (batchTile * 3 * nDstHeight * nDstPitch);
if(cropW == 0 || cropH == 0) {
if (cropW == 0 || cropH == 0) {
cropX = 0;
cropY = 0;
cropW = nSrcWidth;
cropH = nSrcHeight;
}
float scaleX = (cropW*1.0f / nDstWidth);
float scaleY = (cropH*1.0f / nDstHeight);
float scaleX = (cropW * 1.0f / nDstWidth);
float scaleY = (cropH * 1.0f / nDstHeight);
if(whSameResizeRatio == true)
if (whSameResizeRatio == true)
scaleX = scaleY = scaleX > scaleY ? scaleX : scaleY;
dim3 block(32, 32, 1);
size_t blockDimZ = bs;
// Restricting blocks in Z-dim till 32 to not launch too many blocks
blockDimZ = (blockDimZ > 32) ? 32 : blockDimZ;
dim3 grid((cropW*1.0f/scaleX + block.x - 1) / block.x,
(cropH*1.0f/scaleY + block.y - 1) / block.y, blockDimZ);
resizeBGRplanarBatchKernel<<<grid, block, 0, stream>>>
(texSrc[iTile], dpDstNew, nDstPitch, nDstHeight, nSrcHeight,
bs, scaleX, scaleY, cropX, cropY, cropW, cropH);
dim3 grid((cropW * 1.0f / scaleX + block.x - 1) / block.x,
(cropH * 1.0f / scaleY + block.y - 1) / block.y,
blockDimZ);
resizeBGRplanarBatchKernel<<<grid, block, 0, stream>>>(
texSrc[iTile], dpDstNew, nDstPitch, nDstHeight, nSrcHeight, bs, scaleX, scaleY, cropX, cropY, cropW, cropH);
}
for (iTile = 0; iTile < nTiles; ++iTile)
checkCudaErrors(cudaDestroyTextureObject(texSrc[iTile]));
}
void resizeBGRplanarBatch(
float *dpSrc, int nSrcPitch, int nSrcWidth, int nSrcHeight,
float *dpDst, int nDstPitch, int nDstWidth, int nDstHeight,
int nBatchSize, cudaStream_t stream,
int cropX, int cropY, int cropW, int cropH, bool whSameResizeRatio) {
resizeBGRplanarBatchCore(dpSrc, nSrcPitch, nSrcWidth, nSrcHeight,
dpDst, nDstPitch, nDstWidth, nDstHeight, nBatchSize, stream,
whSameResizeRatio, cropX, cropY, cropW, cropH);
void resizeBGRplanarBatch(float *dpSrc,
int nSrcPitch,
int nSrcWidth,
int nSrcHeight,
float *dpDst,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize,
cudaStream_t stream,
int cropX,
int cropY,
int cropW,
int cropH,
bool whSameResizeRatio)
{
resizeBGRplanarBatchCore(dpSrc,
nSrcPitch,
nSrcWidth,
nSrcHeight,
dpDst,
nDstPitch,
nDstWidth,
nDstHeight,
nBatchSize,
stream,
whSameResizeRatio,
cropX,
cropY,
cropW,
cropH);
}

View File

@@ -29,84 +29,94 @@
#include <cuda.h>
#include <cuda_runtime.h>
#include "resize_convert.h"
__global__ static void resizeNV12BatchKernel(cudaTextureObject_t texSrcLuma,
cudaTextureObject_t texSrcChroma,
uint8_t *pDstNv12, int nSrcWidth,
int nSrcHeight, int nDstPitch,
int nDstWidth, int nDstHeight,
int nBatchSize) {
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
uint8_t *pDstNv12,
int nSrcWidth,
int nSrcHeight,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int px = x * 2, py = y * 2;
int px = x * 2, py = y * 2;
if ((px + 1) >= nDstWidth || (py + 1) >= nDstHeight) return;
if ((px + 1) >= nDstWidth || (py + 1) >= nDstHeight)
return;
float fxScale = 1.0f * nSrcWidth / nDstWidth;
float fyScale = 1.0f * nSrcHeight / nDstHeight;
float fxScale = 1.0f * nSrcWidth / nDstWidth;
float fyScale = 1.0f * nSrcHeight / nDstHeight;
uint8_t *p = pDstNv12 + px + py * nDstPitch;
int hh = nDstHeight * 3 / 2;
int nByte = nDstPitch * hh;
int px_fxScale = px * fxScale;
int px_fxScale_1 = (px + 1) * fxScale;
int py_fyScale = py * fyScale;
int py_fyScale_1 = (py + 1) * fyScale;
uint8_t *p = pDstNv12 + px + py * nDstPitch;
int hh = nDstHeight * 3 / 2;
int nByte = nDstPitch * hh;
int px_fxScale = px * fxScale;
int px_fxScale_1 = (px + 1) * fxScale;
int py_fyScale = py * fyScale;
int py_fyScale_1 = (py + 1) * fyScale;
for (int i = blockIdx.z; i < nBatchSize; i+=gridDim.z) {
*(uchar2 *)p = make_uchar2(tex2D<uint8_t>(texSrcLuma, px_fxScale, py_fyScale),
tex2D<uint8_t>(texSrcLuma, px_fxScale_1, py_fyScale));
*(uchar2 *)(p + nDstPitch) =
make_uchar2(tex2D<uint8_t>(texSrcLuma, px_fxScale, py_fyScale_1),
tex2D<uint8_t>(texSrcLuma, px_fxScale_1, py_fyScale_1));
*(uchar2 *)(p + (nDstHeight - y) * nDstPitch) = tex2D<uchar2>(
texSrcChroma, x * fxScale, (hh * i + nDstHeight + y) * fyScale);
p += nByte;
py += hh;
}
for (int i = blockIdx.z; i < nBatchSize; i += gridDim.z) {
*(uchar2 *)p = make_uchar2(tex2D<uint8_t>(texSrcLuma, px_fxScale, py_fyScale),
tex2D<uint8_t>(texSrcLuma, px_fxScale_1, py_fyScale));
*(uchar2 *)(p + nDstPitch) = make_uchar2(tex2D<uint8_t>(texSrcLuma, px_fxScale, py_fyScale_1),
tex2D<uint8_t>(texSrcLuma, px_fxScale_1, py_fyScale_1));
*(uchar2 *)(p + (nDstHeight - y) * nDstPitch) =
tex2D<uchar2>(texSrcChroma, x * fxScale, (hh * i + nDstHeight + y) * fyScale);
p += nByte;
py += hh;
}
}
void resizeNV12Batch(uint8_t *dpSrc, int nSrcPitch, int nSrcWidth,
int nSrcHeight, uint8_t *dpDst, int nDstPitch,
int nDstWidth, int nDstHeight, int nBatchSize,
cudaStream_t stream) {
int hhSrc = ceilf(nSrcHeight * 3.0f / 2.0f);
cudaResourceDesc resDesc = {};
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = dpSrc;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uint8_t>();
resDesc.res.pitch2D.width = nSrcWidth;
resDesc.res.pitch2D.height = hhSrc * nBatchSize;
resDesc.res.pitch2D.pitchInBytes = nSrcPitch;
void resizeNV12Batch(uint8_t *dpSrc,
int nSrcPitch,
int nSrcWidth,
int nSrcHeight,
uint8_t *dpDst,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize,
cudaStream_t stream)
{
int hhSrc = ceilf(nSrcHeight * 3.0f / 2.0f);
cudaResourceDesc resDesc = {};
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = dpSrc;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uint8_t>();
resDesc.res.pitch2D.width = nSrcWidth;
resDesc.res.pitch2D.height = hhSrc * nBatchSize;
resDesc.res.pitch2D.pitchInBytes = nSrcPitch;
cudaTextureDesc texDesc = {};
texDesc.filterMode = cudaFilterModePoint;
texDesc.readMode = cudaReadModeElementType;
cudaTextureDesc texDesc = {};
texDesc.filterMode = cudaFilterModePoint;
texDesc.readMode = cudaReadModeElementType;
cudaTextureObject_t texLuma = 0;
checkCudaErrors(cudaCreateTextureObject(&texLuma, &resDesc, &texDesc, NULL));
cudaTextureObject_t texLuma = 0;
checkCudaErrors(cudaCreateTextureObject(&texLuma, &resDesc, &texDesc, NULL));
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uchar2>();
resDesc.res.pitch2D.width /= 2;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<uchar2>();
resDesc.res.pitch2D.width /= 2;
cudaTextureObject_t texChroma = 0;
checkCudaErrors(cudaCreateTextureObject(&texChroma, &resDesc, &texDesc, NULL));
cudaTextureObject_t texChroma = 0;
checkCudaErrors(cudaCreateTextureObject(&texChroma, &resDesc, &texDesc, NULL));
dim3 block(32, 32, 1);
dim3 block(32, 32, 1);
size_t blockDimZ = nBatchSize;
size_t blockDimZ = nBatchSize;
// Restricting blocks in Z-dim till 32 to not launch too many blocks
blockDimZ = (blockDimZ > 32) ? 32 : blockDimZ;
// Restricting blocks in Z-dim till 32 to not launch too many blocks
blockDimZ = (blockDimZ > 32) ? 32 : blockDimZ;
dim3 grid((nDstWidth / 2 + block.x) / block.x,
(nDstHeight / 2 + block.y) / block.y, blockDimZ);
resizeNV12BatchKernel<<<grid, block, 0, stream>>>(
texLuma, texChroma, dpDst, nSrcWidth, nSrcHeight, nDstPitch, nDstWidth,
nDstHeight, nBatchSize);
dim3 grid((nDstWidth / 2 + block.x) / block.x, (nDstHeight / 2 + block.y) / block.y, blockDimZ);
resizeNV12BatchKernel<<<grid, block, 0, stream>>>(
texLuma, texChroma, dpDst, nSrcWidth, nSrcHeight, nDstPitch, nDstWidth, nDstHeight, nBatchSize);
checkCudaErrors(cudaDestroyTextureObject(texLuma));
checkCudaErrors(cudaDestroyTextureObject(texChroma));
checkCudaErrors(cudaDestroyTextureObject(texLuma));
checkCudaErrors(cudaDestroyTextureObject(texChroma));
}

View File

@@ -36,119 +36,124 @@
#define CONV_THREADS_X 64
#define CONV_THREADS_Y 10
__forceinline__ __device__ static float clampF(float x, float lower,
float upper) {
return x < lower ? lower : (x > upper ? upper : x);
__forceinline__ __device__ static float clampF(float x, float lower, float upper)
{
return x < lower ? lower : (x > upper ? upper : x);
}
__global__ static void nv12ToBGRplanarBatchKernel(const uint8_t *pNv12,
int nNv12Pitch, float *pBgr,
int nRgbPitch, int nWidth,
int nHeight, int nBatchSize) {
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int nNv12Pitch,
float *pBgr,
int nRgbPitch,
int nWidth,
int nHeight,
int nBatchSize)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
if ((x << 2) + 1 > nWidth || (y << 1) + 1 > nHeight) return;
if ((x << 2) + 1 > nWidth || (y << 1) + 1 > nHeight)
return;
const uint8_t *__restrict__ pSrc = pNv12;
const uint8_t *__restrict__ pSrc = pNv12;
for (int i = blockIdx.z; i < nBatchSize; i += gridDim.z) {
pSrc = pNv12 + i * ((nHeight * nNv12Pitch * 3) >> 1) + (x << 2) +
(y << 1) * nNv12Pitch;
uchar4 luma2x01, luma2x23, uv2;
*(uint32_t *)&luma2x01 = *(uint32_t *)pSrc;
*(uint32_t *)&luma2x23 = *(uint32_t *)(pSrc + nNv12Pitch);
*(uint32_t *)&uv2 = *(uint32_t *)(pSrc + (nHeight - y) * nNv12Pitch);
for (int i = blockIdx.z; i < nBatchSize; i += gridDim.z) {
pSrc = pNv12 + i * ((nHeight * nNv12Pitch * 3) >> 1) + (x << 2) + (y << 1) * nNv12Pitch;
uchar4 luma2x01, luma2x23, uv2;
*(uint32_t *)&luma2x01 = *(uint32_t *)pSrc;
*(uint32_t *)&luma2x23 = *(uint32_t *)(pSrc + nNv12Pitch);
*(uint32_t *)&uv2 = *(uint32_t *)(pSrc + (nHeight - y) * nNv12Pitch);
float *pDstBlock = (pBgr + i * ((nHeight * nRgbPitch * 3) >> 2) +
((blockIdx.x * blockDim.x) << 2) +
((blockIdx.y * blockDim.y) << 1) * (nRgbPitch >> 2));
float *pDstBlock = (pBgr + i * ((nHeight * nRgbPitch * 3) >> 2) + ((blockIdx.x * blockDim.x) << 2)
+ ((blockIdx.y * blockDim.y) << 1) * (nRgbPitch >> 2));
float2 add1;
float2 add2;
float2 add3;
float2 add00, add01, add02, add03;
float2 d, e;
float2 add1;
float2 add2;
float2 add3;
float2 add00, add01, add02, add03;
float2 d, e;
add00.x = 1.1644f * luma2x01.x;
add01.x = 1.1644f * luma2x01.y;
add00.y = 1.1644f * luma2x01.z;
add01.y = 1.1644f * luma2x01.w;
add00.x = 1.1644f * luma2x01.x;
add01.x = 1.1644f * luma2x01.y;
add00.y = 1.1644f * luma2x01.z;
add01.y = 1.1644f * luma2x01.w;
add02.x = 1.1644f * luma2x23.x;
add03.x = 1.1644f * luma2x23.y;
add02.y = 1.1644f * luma2x23.z;
add03.y = 1.1644f * luma2x23.w;
add02.x = 1.1644f * luma2x23.x;
add03.x = 1.1644f * luma2x23.y;
add02.y = 1.1644f * luma2x23.z;
add03.y = 1.1644f * luma2x23.w;
d.x = uv2.x - 128.0f;
e.x = uv2.y - 128.0f;
d.y = uv2.z - 128.0f;
e.y = uv2.w - 128.0f;
d.x = uv2.x - 128.0f;
e.x = uv2.y - 128.0f;
d.y = uv2.z - 128.0f;
e.y = uv2.w - 128.0f;
add1.x = 2.0172f * d.x;
add1.y = 2.0172f * d.y;
add1.x = 2.0172f * d.x;
add1.y = 2.0172f * d.y;
add2.x = (-0.3918f) * d.x + (-0.8130f) * e.x;
add2.y = (-0.3918f) * d.y + (-0.8130f) * e.y;
add2.x = (-0.3918f) * d.x + (-0.8130f) * e.x;
add2.y = (-0.3918f) * d.y + (-0.8130f) * e.y;
add3.x = 1.5960f * e.x;
add3.y = 1.5960f * e.y;
add3.x = 1.5960f * e.x;
add3.y = 1.5960f * e.y;
int rowStride = (threadIdx.y << 1) * (nRgbPitch >> 2);
int nextRowStride = ((threadIdx.y << 1) + 1) * (nRgbPitch >> 2);
// B
*((float4 *)&pDstBlock[rowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add00.x + add1.x, 0.0f, 255.0f),
clampF(add01.x + add1.x, 0.0f, 255.0f),
clampF(add00.y + add1.y, 0.0f, 255.0f),
clampF(add01.y + add1.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[nextRowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add1.x, 0.0f, 255.0f),
clampF(add03.x + add1.x, 0.0f, 255.0f),
clampF(add02.y + add1.y, 0.0f, 255.0f),
clampF(add03.y + add1.y, 0.0f, 255.0f));
int rowStride = (threadIdx.y << 1) * (nRgbPitch >> 2);
int nextRowStride = ((threadIdx.y << 1) + 1) * (nRgbPitch >> 2);
// B
*((float4 *)&pDstBlock[rowStride + (threadIdx.x << 2)]) = make_float4(clampF(add00.x + add1.x, 0.0f, 255.0f),
clampF(add01.x + add1.x, 0.0f, 255.0f),
clampF(add00.y + add1.y, 0.0f, 255.0f),
clampF(add01.y + add1.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[nextRowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add1.x, 0.0f, 255.0f),
clampF(add03.x + add1.x, 0.0f, 255.0f),
clampF(add02.y + add1.y, 0.0f, 255.0f),
clampF(add03.y + add1.y, 0.0f, 255.0f));
int planeStride = nHeight * nRgbPitch >> 2;
// G
*((float4 *)&pDstBlock[planeStride + rowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add00.x + add2.x, 0.0f, 255.0f),
clampF(add01.x + add2.x, 0.0f, 255.0f),
clampF(add00.y + add2.y, 0.0f, 255.0f),
clampF(add01.y + add2.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[planeStride + nextRowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add2.x, 0.0f, 255.0f),
clampF(add03.x + add2.x, 0.0f, 255.0f),
clampF(add02.y + add2.y, 0.0f, 255.0f),
clampF(add03.y + add2.y, 0.0f, 255.0f));
int planeStride = nHeight * nRgbPitch >> 2;
// G
*((float4 *)&pDstBlock[planeStride + rowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add00.x + add2.x, 0.0f, 255.0f),
clampF(add01.x + add2.x, 0.0f, 255.0f),
clampF(add00.y + add2.y, 0.0f, 255.0f),
clampF(add01.y + add2.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[planeStride + nextRowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add2.x, 0.0f, 255.0f),
clampF(add03.x + add2.x, 0.0f, 255.0f),
clampF(add02.y + add2.y, 0.0f, 255.0f),
clampF(add03.y + add2.y, 0.0f, 255.0f));
// R
*((float4
*)&pDstBlock[(planeStride << 1) + rowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add00.x + add3.x, 0.0f, 255.0f),
clampF(add01.x + add3.x, 0.0f, 255.0f),
clampF(add00.y + add3.y, 0.0f, 255.0f),
clampF(add01.y + add3.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[(planeStride << 1) + nextRowStride +
(threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add3.x, 0.0f, 255.0f),
clampF(add03.x + add3.x, 0.0f, 255.0f),
clampF(add02.y + add3.y, 0.0f, 255.0f),
clampF(add03.y + add3.y, 0.0f, 255.0f));
}
// R
*((float4 *)&pDstBlock[(planeStride << 1) + rowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add00.x + add3.x, 0.0f, 255.0f),
clampF(add01.x + add3.x, 0.0f, 255.0f),
clampF(add00.y + add3.y, 0.0f, 255.0f),
clampF(add01.y + add3.y, 0.0f, 255.0f));
*((float4 *)&pDstBlock[(planeStride << 1) + nextRowStride + (threadIdx.x << 2)]) =
make_float4(clampF(add02.x + add3.x, 0.0f, 255.0f),
clampF(add03.x + add3.x, 0.0f, 255.0f),
clampF(add02.y + add3.y, 0.0f, 255.0f),
clampF(add03.y + add3.y, 0.0f, 255.0f));
}
}
void nv12ToBGRplanarBatch(uint8_t *pNv12, int nNv12Pitch, float *pBgr,
int nRgbPitch, int nWidth, int nHeight,
int nBatchSize, cudaStream_t stream) {
dim3 threads(CONV_THREADS_X, CONV_THREADS_Y);
void nv12ToBGRplanarBatch(uint8_t *pNv12,
int nNv12Pitch,
float *pBgr,
int nRgbPitch,
int nWidth,
int nHeight,
int nBatchSize,
cudaStream_t stream)
{
dim3 threads(CONV_THREADS_X, CONV_THREADS_Y);
size_t blockDimZ = nBatchSize;
size_t blockDimZ = nBatchSize;
// Restricting blocks in Z-dim till 32 to not launch too many blocks
blockDimZ = (blockDimZ > 32) ? 32 : blockDimZ;
// Restricting blocks in Z-dim till 32 to not launch too many blocks
blockDimZ = (blockDimZ > 32) ? 32 : blockDimZ;
dim3 blocks((nWidth / 4 - 1) / threads.x + 1,
(nHeight / 2 - 1) / threads.y + 1, blockDimZ);
nv12ToBGRplanarBatchKernel<<<blocks, threads, 0, stream>>>(
pNv12, nNv12Pitch, pBgr, nRgbPitch, nWidth, nHeight, nBatchSize);
dim3 blocks((nWidth / 4 - 1) / threads.x + 1, (nHeight / 2 - 1) / threads.y + 1, blockDimZ);
nv12ToBGRplanarBatchKernel<<<blocks, threads, 0, stream>>>(
pNv12, nNv12Pitch, pBgr, nRgbPitch, nWidth, nHeight, nBatchSize);
}

View File

@@ -29,28 +29,45 @@
#ifndef __H_RESIZE_CONVERT__
#define __H_RESIZE_CONVERT__
#include <iostream>
#include <helper_cuda.h>
#include <iostream>
// nv12 resize
extern "C"
void resizeNV12Batch(
uint8_t *dpSrc, int nSrcPitch, int nSrcWidth, int nSrcHeight,
uint8_t *dpDst, int nDstPitch, int nDstWidth, int nDstHeight,
int nBatchSize, cudaStream_t stream = 0);
extern "C" void resizeNV12Batch(uint8_t *dpSrc,
int nSrcPitch,
int nSrcWidth,
int nSrcHeight,
uint8_t *dpDst,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize,
cudaStream_t stream = 0);
// bgr resize
extern "C"
void resizeBGRplanarBatch(
float *dpSrc, int nSrcPitch, int nSrcWidth, int nSrcHeight,
float *dpDst, int nDstPitch, int nDstWidth, int nDstHeight,
int nBatchSize, cudaStream_t stream = 0,
int cropX = 0, int cropY = 0, int cropW = 0, int cropH = 0,
bool whSameResizeRatio = false);
extern "C" void resizeBGRplanarBatch(float *dpSrc,
int nSrcPitch,
int nSrcWidth,
int nSrcHeight,
float *dpDst,
int nDstPitch,
int nDstWidth,
int nDstHeight,
int nBatchSize,
cudaStream_t stream = 0,
int cropX = 0,
int cropY = 0,
int cropW = 0,
int cropH = 0,
bool whSameResizeRatio = false);
//NV12 to bgr planar
extern "C"
void nv12ToBGRplanarBatch(uint8_t *pNv12, int nNv12Pitch,
float *pRgb, int nRgbPitch, int nWidth, int nHeight,
int nBatchSize, cudaStream_t stream=0);
// NV12 to bgr planar
extern "C" void nv12ToBGRplanarBatch(uint8_t *pNv12,
int nNv12Pitch,
float *pRgb,
int nRgbPitch,
int nWidth,
int nHeight,
int nBatchSize,
cudaStream_t stream = 0);
#endif

View File

@@ -51,398 +51,424 @@ Run
*/
#include <cassert>
#include <cuda.h>
#include <cuda_runtime.h>
#include <fstream>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <fstream>
#include <iostream>
#include <memory>
#include "resize_convert.h"
#include "utils.h"
#define TEST_LOOP 20
typedef struct _nv12_to_bgr24_context_t {
int width;
int height;
int pitch;
typedef struct _nv12_to_bgr24_context_t
{
int width;
int height;
int pitch;
int dst_width;
int dst_height;
int dst_pitch;
int dst_width;
int dst_height;
int dst_pitch;
int batch;
int device; // cuda device ID
int batch;
int device; // cuda device ID
char *input_nv12_file;
char *input_nv12_file;
int ctx_pitch; // the value will be suitable for Texture memroy.
int ctx_heights; // the value will be even.
int ctx_pitch; // the value will be suitable for Texture memroy.
int ctx_heights; // the value will be even.
} nv12_to_bgr24_context;
nv12_to_bgr24_context g_ctx;
static void printHelp(const char *app_name) {
std::cout << "Usage:" << app_name << " [options]\n\n";
std::cout << "OPTIONS:\n";
std::cout << "\t-h,--help\n\n";
std::cout << "\t-input=nv12file nv12 input file\n";
std::cout
<< "\t-width=width input nv12 image width, <1 -- 4096>\n";
std::cout
<< "\t-height=height input nv12 image height, <1 -- 4096>\n";
std::cout
<< "\t-pitch=pitch(optional) input nv12 image pitch, <0 -- 4096>\n";
std::cout
<< "\t-dst_width=width output BGR image width, <1 -- 4096>\n";
std::cout
<< "\t-dst_height=height output BGR image height, <1 -- 4096>\n";
std::cout
<< "\t-dst_pitch=pitch(optional) output BGR image pitch, <0 -- 4096>\n";
std::cout
<< "\t-batch=batch process frames count, <1 -- 4096>\n\n";
std::cout
<< "\t-device=device_num(optional) cuda device number, <0 -- 4096>\n\n";
static void printHelp(const char *app_name)
{
std::cout << "Usage:" << app_name << " [options]\n\n";
std::cout << "OPTIONS:\n";
std::cout << "\t-h,--help\n\n";
std::cout << "\t-input=nv12file nv12 input file\n";
std::cout << "\t-width=width input nv12 image width, <1 -- 4096>\n";
std::cout << "\t-height=height input nv12 image height, <1 -- 4096>\n";
std::cout << "\t-pitch=pitch(optional) input nv12 image pitch, <0 -- 4096>\n";
std::cout << "\t-dst_width=width output BGR image width, <1 -- 4096>\n";
std::cout << "\t-dst_height=height output BGR image height, <1 -- 4096>\n";
std::cout << "\t-dst_pitch=pitch(optional) output BGR image pitch, <0 -- 4096>\n";
std::cout << "\t-batch=batch process frames count, <1 -- 4096>\n\n";
std::cout << "\t-device=device_num(optional) cuda device number, <0 -- 4096>\n\n";
return;
return;
}
int parseCmdLine(int argc, char *argv[]) {
char **argp = (char **)argv;
char *arg = (char *)argv[0];
int parseCmdLine(int argc, char *argv[])
{
char **argp = (char **)argv;
char *arg = (char *)argv[0];
memset(&g_ctx, 0, sizeof(g_ctx));
memset(&g_ctx, 0, sizeof(g_ctx));
if ((arg && (!strcmp(arg, "-h") || !strcmp(arg, "--help")))) {
printHelp(argv[0]);
return -1;
}
if (argc == 1) {
// Run using default arguments
g_ctx.input_nv12_file = sdkFindFilePath("test1920x1080.nv12", argv[0]);
if (g_ctx.input_nv12_file == NULL) {
printf("Cannot find input file test1920x1080.nv12\n Exiting\n");
return EXIT_FAILURE;
}
g_ctx.width = 1920;
g_ctx.height = 1080;
g_ctx.dst_width = 640;
g_ctx.dst_height = 480;
g_ctx.batch = 24;
} else if (argc > 1) {
if (checkCmdLineFlag(argc, (const char **)argv, "width")) {
g_ctx.width = getCmdLineArgumentInt(argc, (const char **)argv, "width");
if ((arg && (!strcmp(arg, "-h") || !strcmp(arg, "--help")))) {
printHelp(argv[0]);
return -1;
}
if (checkCmdLineFlag(argc, (const char **)argv, "height")) {
g_ctx.height = getCmdLineArgumentInt(argc, (const char **)argv, "height");
if (argc == 1) {
// Run using default arguments
g_ctx.input_nv12_file = sdkFindFilePath("test1920x1080.nv12", argv[0]);
if (g_ctx.input_nv12_file == NULL) {
printf("Cannot find input file test1920x1080.nv12\n Exiting\n");
return EXIT_FAILURE;
}
g_ctx.width = 1920;
g_ctx.height = 1080;
g_ctx.dst_width = 640;
g_ctx.dst_height = 480;
g_ctx.batch = 24;
}
else if (argc > 1) {
if (checkCmdLineFlag(argc, (const char **)argv, "width")) {
g_ctx.width = getCmdLineArgumentInt(argc, (const char **)argv, "width");
}
if (checkCmdLineFlag(argc, (const char **)argv, "height")) {
g_ctx.height = getCmdLineArgumentInt(argc, (const char **)argv, "height");
}
if (checkCmdLineFlag(argc, (const char **)argv, "pitch")) {
g_ctx.pitch = getCmdLineArgumentInt(argc, (const char **)argv, "pitch");
}
if (checkCmdLineFlag(argc, (const char **)argv, "input")) {
getCmdLineArgumentString(argc, (const char **)argv, "input", (char **)&g_ctx.input_nv12_file);
}
if (checkCmdLineFlag(argc, (const char **)argv, "dst_width")) {
g_ctx.dst_width = getCmdLineArgumentInt(argc, (const char **)argv, "dst_width");
}
if (checkCmdLineFlag(argc, (const char **)argv, "dst_height")) {
g_ctx.dst_height = getCmdLineArgumentInt(argc, (const char **)argv, "dst_height");
}
if (checkCmdLineFlag(argc, (const char **)argv, "dst_pitch")) {
g_ctx.dst_pitch = getCmdLineArgumentInt(argc, (const char **)argv, "dst_pitch");
}
if (checkCmdLineFlag(argc, (const char **)argv, "batch")) {
g_ctx.batch = getCmdLineArgumentInt(argc, (const char **)argv, "batch");
}
}
if (checkCmdLineFlag(argc, (const char **)argv, "pitch")) {
g_ctx.pitch = getCmdLineArgumentInt(argc, (const char **)argv, "pitch");
g_ctx.device = findCudaDevice(argc, (const char **)argv);
if ((g_ctx.width == 0) || (g_ctx.height == 0) || (g_ctx.dst_width == 0) || (g_ctx.dst_height == 0)
|| !g_ctx.input_nv12_file) {
printHelp(argv[0]);
return -1;
}
if (checkCmdLineFlag(argc, (const char **)argv, "input")) {
getCmdLineArgumentString(argc, (const char **)argv, "input",
(char **)&g_ctx.input_nv12_file);
}
if (g_ctx.pitch == 0)
g_ctx.pitch = g_ctx.width;
if (g_ctx.dst_pitch == 0)
g_ctx.dst_pitch = g_ctx.dst_width;
if (checkCmdLineFlag(argc, (const char **)argv, "dst_width")) {
g_ctx.dst_width =
getCmdLineArgumentInt(argc, (const char **)argv, "dst_width");
}
if (checkCmdLineFlag(argc, (const char **)argv, "dst_height")) {
g_ctx.dst_height =
getCmdLineArgumentInt(argc, (const char **)argv, "dst_height");
}
if (checkCmdLineFlag(argc, (const char **)argv, "dst_pitch")) {
g_ctx.dst_pitch =
getCmdLineArgumentInt(argc, (const char **)argv, "dst_pitch");
}
if (checkCmdLineFlag(argc, (const char **)argv, "batch")) {
g_ctx.batch = getCmdLineArgumentInt(argc, (const char **)argv, "batch");
}
}
g_ctx.device = findCudaDevice(argc, (const char **)argv);
if ((g_ctx.width == 0) || (g_ctx.height == 0) || (g_ctx.dst_width == 0) ||
(g_ctx.dst_height == 0) || !g_ctx.input_nv12_file) {
printHelp(argv[0]);
return -1;
}
if (g_ctx.pitch == 0) g_ctx.pitch = g_ctx.width;
if (g_ctx.dst_pitch == 0) g_ctx.dst_pitch = g_ctx.dst_width;
return 0;
return 0;
}
/*
load nv12 yuvfile data into GPU device memory with batch of copy
*/
static int loadNV12Frame(unsigned char *d_inputNV12) {
unsigned char *pNV12FrameData;
unsigned char *d_nv12;
int frameSize;
std::ifstream nv12File(g_ctx.input_nv12_file, std::ifstream::in | std::ios::binary);
static int loadNV12Frame(unsigned char *d_inputNV12)
{
unsigned char *pNV12FrameData;
unsigned char *d_nv12;
int frameSize;
std::ifstream nv12File(g_ctx.input_nv12_file, std::ifstream::in | std::ios::binary);
if (!nv12File.is_open()) {
std::cerr << "Can't open files\n";
return -1;
}
if (!nv12File.is_open()) {
std::cerr << "Can't open files\n";
return -1;
}
frameSize = g_ctx.pitch * g_ctx.ctx_heights;
frameSize = g_ctx.pitch * g_ctx.ctx_heights;
#if USE_UVM_MEM
pNV12FrameData = d_inputNV12;
pNV12FrameData = d_inputNV12;
#else
pNV12FrameData = (unsigned char *)malloc(frameSize);
if (pNV12FrameData == NULL) {
std::cerr << "Failed to malloc pNV12FrameData\n";
return -1;
}
pNV12FrameData = (unsigned char *)malloc(frameSize);
if (pNV12FrameData == NULL) {
std::cerr << "Failed to malloc pNV12FrameData\n";
return -1;
}
#endif
nv12File.read((char *)pNV12FrameData, frameSize);
nv12File.read((char *)pNV12FrameData, frameSize);
if (nv12File.gcount() < frameSize) {
std::cerr << "can't get one frame!\n";
return -1;
}
if (nv12File.gcount() < frameSize) {
std::cerr << "can't get one frame!\n";
return -1;
}
#if USE_UVM_MEM
// Prefetch to GPU for following GPU operation
cudaStreamAttachMemAsync(NULL, pNV12FrameData, 0, cudaMemAttachGlobal);
// Prefetch to GPU for following GPU operation
cudaStreamAttachMemAsync(NULL, pNV12FrameData, 0, cudaMemAttachGlobal);
#endif
// expand one frame to multi frames for batch processing
d_nv12 = d_inputNV12;
for (int i = 0; i < g_ctx.batch; i++) {
checkCudaErrors(cudaMemcpy2D((void *)d_nv12, g_ctx.ctx_pitch,
pNV12FrameData, g_ctx.width, g_ctx.width,
g_ctx.ctx_heights, cudaMemcpyHostToDevice));
// expand one frame to multi frames for batch processing
d_nv12 = d_inputNV12;
for (int i = 0; i < g_ctx.batch; i++) {
checkCudaErrors(cudaMemcpy2D((void *)d_nv12,
g_ctx.ctx_pitch,
pNV12FrameData,
g_ctx.width,
g_ctx.width,
g_ctx.ctx_heights,
cudaMemcpyHostToDevice));
d_nv12 += g_ctx.ctx_pitch * g_ctx.ctx_heights;
}
d_nv12 += g_ctx.ctx_pitch * g_ctx.ctx_heights;
}
#if (USE_UVM_MEM == 0)
free(pNV12FrameData);
free(pNV12FrameData);
#endif
nv12File.close();
nv12File.close();
return 0;
return 0;
}
/*
1. resize interlace nv12 to target size
2. convert nv12 to bgr 3 progressive planars
*/
void nv12ResizeAndNV12ToBGR(unsigned char *d_inputNV12) {
unsigned char *d_resizedNV12;
float *d_outputBGR;
int size;
char filename[40];
void nv12ResizeAndNV12ToBGR(unsigned char *d_inputNV12)
{
unsigned char *d_resizedNV12;
float *d_outputBGR;
int size;
char filename[40];
/* allocate device memory for resized nv12 output */
size = g_ctx.dst_width * ceil(g_ctx.dst_height * 3.0f / 2.0f) * g_ctx.batch *
sizeof(unsigned char);
checkCudaErrors(cudaMalloc((void **)&d_resizedNV12, size));
/* allocate device memory for resized nv12 output */
size = g_ctx.dst_width * ceil(g_ctx.dst_height * 3.0f / 2.0f) * g_ctx.batch * sizeof(unsigned char);
checkCudaErrors(cudaMalloc((void **)&d_resizedNV12, size));
/* allocate device memory for bgr output */
size = g_ctx.dst_pitch * g_ctx.dst_height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_outputBGR, size));
/* allocate device memory for bgr output */
size = g_ctx.dst_pitch * g_ctx.dst_height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_outputBGR, size));
cudaStream_t stream;
checkCudaErrors(cudaStreamCreate(&stream));
/* create cuda event handles */
cudaEvent_t start, stop;
checkCudaErrors(cudaEventCreate(&start));
checkCudaErrors(cudaEventCreate(&stop));
float elapsedTime = 0.0f;
cudaStream_t stream;
checkCudaErrors(cudaStreamCreate(&stream));
/* create cuda event handles */
cudaEvent_t start, stop;
checkCudaErrors(cudaEventCreate(&start));
checkCudaErrors(cudaEventCreate(&stop));
float elapsedTime = 0.0f;
/* resize interlace nv12 */
/* resize interlace nv12 */
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
resizeNV12Batch(d_inputNV12, g_ctx.ctx_pitch, g_ctx.width, g_ctx.height,
d_resizedNV12, g_ctx.dst_width, g_ctx.dst_width,
g_ctx.dst_height, g_ctx.batch);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
resizeNV12Batch(d_inputNV12,
g_ctx.ctx_pitch,
g_ctx.width,
g_ctx.height,
d_resizedNV12,
g_ctx.dst_width,
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.batch);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(
" CUDA resize nv12(%dx%d --> %dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width, g_ctx.height, g_ctx.dst_width, g_ctx.dst_height, g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(" CUDA resize nv12(%dx%d --> %dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width,
g_ctx.height,
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
sprintf(filename, "resized_nv12_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
sprintf(filename, "resized_nv12_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
/* convert nv12 to bgr 3 progressive planars */
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
nv12ToBGRplanarBatch(d_resizedNV12, g_ctx.dst_pitch, // intput
d_outputBGR,
g_ctx.dst_pitch * sizeof(float), // output
g_ctx.dst_width, g_ctx.dst_height, // output
g_ctx.batch, 0);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
/* convert nv12 to bgr 3 progressive planars */
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
nv12ToBGRplanarBatch(d_resizedNV12,
g_ctx.dst_pitch, // intput
d_outputBGR,
g_ctx.dst_pitch * sizeof(float), // output
g_ctx.dst_width,
g_ctx.dst_height, // output
g_ctx.batch,
0);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(
" CUDA convert nv12(%dx%d) to bgr(%dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.dst_width, g_ctx.dst_height, g_ctx.dst_width, g_ctx.dst_height,
g_ctx.batch, (elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
printf(" CUDA convert nv12(%dx%d) to bgr(%dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
sprintf(filename, "converted_bgr_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
dumpBGR(d_outputBGR, g_ctx.dst_pitch, g_ctx.dst_width, g_ctx.dst_height,
g_ctx.batch, (char *)"t1", filename);
sprintf(filename, "converted_bgr_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
dumpBGR(d_outputBGR, g_ctx.dst_pitch, g_ctx.dst_width, g_ctx.dst_height, g_ctx.batch, (char *)"t1", filename);
/* release resources */
checkCudaErrors(cudaEventDestroy(start));
checkCudaErrors(cudaEventDestroy(stop));
checkCudaErrors(cudaStreamDestroy(stream));
checkCudaErrors(cudaFree(d_resizedNV12));
checkCudaErrors(cudaFree(d_outputBGR));
/* release resources */
checkCudaErrors(cudaEventDestroy(start));
checkCudaErrors(cudaEventDestroy(stop));
checkCudaErrors(cudaStreamDestroy(stream));
checkCudaErrors(cudaFree(d_resizedNV12));
checkCudaErrors(cudaFree(d_outputBGR));
}
/*
1. convert nv12 to bgr 3 progressive planars
2. resize bgr 3 planars to target size
*/
void nv12ToBGRandBGRresize(unsigned char *d_inputNV12) {
float *d_bgr;
float *d_resizedBGR;
int size;
char filename[40];
void nv12ToBGRandBGRresize(unsigned char *d_inputNV12)
{
float *d_bgr;
float *d_resizedBGR;
int size;
char filename[40];
/* allocate device memory for bgr output */
size = g_ctx.ctx_pitch * g_ctx.height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_bgr, size));
/* allocate device memory for bgr output */
size = g_ctx.ctx_pitch * g_ctx.height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_bgr, size));
/* allocate device memory for resized bgr output */
size = g_ctx.dst_width * g_ctx.dst_height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_resizedBGR, size));
/* allocate device memory for resized bgr output */
size = g_ctx.dst_width * g_ctx.dst_height * 3 * g_ctx.batch * sizeof(float);
checkCudaErrors(cudaMalloc((void **)&d_resizedBGR, size));
cudaStream_t stream;
checkCudaErrors(cudaStreamCreate(&stream));
/* create cuda event handles */
cudaEvent_t start, stop;
checkCudaErrors(cudaEventCreate(&start));
checkCudaErrors(cudaEventCreate(&stop));
float elapsedTime = 0.0f;
cudaStream_t stream;
checkCudaErrors(cudaStreamCreate(&stream));
/* create cuda event handles */
cudaEvent_t start, stop;
checkCudaErrors(cudaEventCreate(&start));
checkCudaErrors(cudaEventCreate(&stop));
float elapsedTime = 0.0f;
/* convert interlace nv12 to bgr 3 progressive planars */
cudaEventRecord(start, 0);
cudaDeviceSynchronize();
for (int i = 0; i < TEST_LOOP; i++) {
nv12ToBGRplanarBatch(d_inputNV12, g_ctx.ctx_pitch, d_bgr,
g_ctx.ctx_pitch * sizeof(float), g_ctx.width,
g_ctx.height, g_ctx.batch, 0);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
/* convert interlace nv12 to bgr 3 progressive planars */
cudaEventRecord(start, 0);
cudaDeviceSynchronize();
for (int i = 0; i < TEST_LOOP; i++) {
nv12ToBGRplanarBatch(d_inputNV12,
g_ctx.ctx_pitch,
d_bgr,
g_ctx.ctx_pitch * sizeof(float),
g_ctx.width,
g_ctx.height,
g_ctx.batch,
0);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(
" CUDA convert nv12(%dx%d) to bgr(%dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width, g_ctx.height, g_ctx.width, g_ctx.height, g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(" CUDA convert nv12(%dx%d) to bgr(%dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width,
g_ctx.height,
g_ctx.width,
g_ctx.height,
g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
sprintf(filename, "converted_bgr_%dx%d", g_ctx.width, g_ctx.height);
sprintf(filename, "converted_bgr_%dx%d", g_ctx.width, g_ctx.height);
/* resize bgr 3 progressive planars */
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
resizeBGRplanarBatch(d_bgr, g_ctx.ctx_pitch, g_ctx.width, g_ctx.height,
d_resizedBGR, g_ctx.dst_width, g_ctx.dst_width,
g_ctx.dst_height, g_ctx.batch);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
/* resize bgr 3 progressive planars */
cudaEventRecord(start, 0);
for (int i = 0; i < TEST_LOOP; i++) {
resizeBGRplanarBatch(d_bgr,
g_ctx.ctx_pitch,
g_ctx.width,
g_ctx.height,
d_resizedBGR,
g_ctx.dst_width,
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.batch);
}
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(
" CUDA resize bgr(%dx%d --> %dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width, g_ctx.height, g_ctx.dst_width, g_ctx.dst_height, g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
cudaEventElapsedTime(&elapsedTime, start, stop);
printf(" CUDA resize bgr(%dx%d --> %dx%d), batch: %d,"
" average time: %.3f ms ==> %.3f ms/frame\n",
g_ctx.width,
g_ctx.height,
g_ctx.dst_width,
g_ctx.dst_height,
g_ctx.batch,
(elapsedTime / (TEST_LOOP * 1.0f)),
(elapsedTime / (TEST_LOOP * 1.0f)) / g_ctx.batch);
memset(filename, 0, sizeof(filename));
sprintf(filename, "resized_bgr_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
dumpBGR(d_resizedBGR, g_ctx.dst_pitch, g_ctx.dst_width, g_ctx.dst_height,
g_ctx.batch, (char *)"t2", filename);
memset(filename, 0, sizeof(filename));
sprintf(filename, "resized_bgr_%dx%d", g_ctx.dst_width, g_ctx.dst_height);
dumpBGR(d_resizedBGR, g_ctx.dst_pitch, g_ctx.dst_width, g_ctx.dst_height, g_ctx.batch, (char *)"t2", filename);
/* release resources */
checkCudaErrors(cudaEventDestroy(start));
checkCudaErrors(cudaEventDestroy(stop));
checkCudaErrors(cudaStreamDestroy(stream));
checkCudaErrors(cudaFree(d_bgr));
checkCudaErrors(cudaFree(d_resizedBGR));
/* release resources */
checkCudaErrors(cudaEventDestroy(start));
checkCudaErrors(cudaEventDestroy(stop));
checkCudaErrors(cudaStreamDestroy(stream));
checkCudaErrors(cudaFree(d_bgr));
checkCudaErrors(cudaFree(d_resizedBGR));
}
int main(int argc, char *argv[]) {
unsigned char *d_inputNV12;
int main(int argc, char *argv[])
{
unsigned char *d_inputNV12;
if (parseCmdLine(argc, argv) < 0) return EXIT_FAILURE;
if (parseCmdLine(argc, argv) < 0)
return EXIT_FAILURE;
g_ctx.ctx_pitch = g_ctx.width;
int ctx_alignment = 32;
g_ctx.ctx_pitch += (g_ctx.ctx_pitch % ctx_alignment != 0)
? (ctx_alignment - g_ctx.ctx_pitch % ctx_alignment)
: 0;
g_ctx.ctx_pitch = g_ctx.width;
int ctx_alignment = 32;
g_ctx.ctx_pitch += (g_ctx.ctx_pitch % ctx_alignment != 0) ? (ctx_alignment - g_ctx.ctx_pitch % ctx_alignment) : 0;
g_ctx.ctx_heights = ceil(g_ctx.height * 3.0f / 2.0f);
g_ctx.ctx_heights = ceil(g_ctx.height * 3.0f / 2.0f);
/* load nv12 yuv data into d_inputNV12 with batch of copies */
/* load nv12 yuv data into d_inputNV12 with batch of copies */
#if USE_UVM_MEM
checkCudaErrors(cudaMallocManaged(
(void **)&d_inputNV12,
(g_ctx.ctx_pitch * g_ctx.ctx_heights * g_ctx.batch), cudaMemAttachHost));
printf("\nUSE_UVM_MEM\n");
checkCudaErrors(cudaMallocManaged(
(void **)&d_inputNV12, (g_ctx.ctx_pitch * g_ctx.ctx_heights * g_ctx.batch), cudaMemAttachHost));
printf("\nUSE_UVM_MEM\n");
#else
checkCudaErrors(
cudaMalloc((void **)&d_inputNV12,
(g_ctx.ctx_pitch * g_ctx.ctx_heights * g_ctx.batch)));
checkCudaErrors(cudaMalloc((void **)&d_inputNV12, (g_ctx.ctx_pitch * g_ctx.ctx_heights * g_ctx.batch)));
#endif
if (loadNV12Frame(d_inputNV12)) {
std::cerr << "failed to load batch data!\n";
return EXIT_FAILURE;
}
if (loadNV12Frame(d_inputNV12)) {
std::cerr << "failed to load batch data!\n";
return EXIT_FAILURE;
}
/* firstly resize nv12, then convert nv12 to bgr */
printf("\nTEST#1:\n");
nv12ResizeAndNV12ToBGR(d_inputNV12);
/* firstly resize nv12, then convert nv12 to bgr */
printf("\nTEST#1:\n");
nv12ResizeAndNV12ToBGR(d_inputNV12);
/* first convert nv12 to bgr, then resize bgr */
printf("\nTEST#2:\n");
nv12ToBGRandBGRresize(d_inputNV12);
/* first convert nv12 to bgr, then resize bgr */
printf("\nTEST#2:\n");
nv12ToBGRandBGRresize(d_inputNV12);
checkCudaErrors(cudaFree(d_inputNV12));
checkCudaErrors(cudaFree(d_inputNV12));
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@@ -25,140 +25,124 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cuda.h>
#include <cuda_runtime.h>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fstream>
#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
#include "resize_convert.h"
#include "utils.h"
__global__ void floatToChar(float *src, unsigned char *dst, int height,
int width, int batchSize)
__global__ void floatToChar(float *src, unsigned char *dst, int height, int width, int batchSize)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int x = threadIdx.x + blockIdx.x * blockDim.x;
if (x >= height * width)
return;
if (x >= height * width)
return;
int offset = height * width * 3;
int offset = height * width * 3;
for (int j = 0; j < batchSize; j++)
{
// b
*(dst + j * offset + x * 3 + 0) =
(unsigned char)*(src + j * offset + height * width * 0 + x);
// g
*(dst + j * offset + x * 3 + 1) =
(unsigned char)*(src + j * offset + height * width * 1 + x);
// r
*(dst + j * offset + x * 3 + 2) =
(unsigned char)*(src + j * offset + height * width * 2 + x);
}
for (int j = 0; j < batchSize; j++) {
// b
*(dst + j * offset + x * 3 + 0) = (unsigned char)*(src + j * offset + height * width * 0 + x);
// g
*(dst + j * offset + x * 3 + 1) = (unsigned char)*(src + j * offset + height * width * 1 + x);
// r
*(dst + j * offset + x * 3 + 2) = (unsigned char)*(src + j * offset + height * width * 2 + x);
}
}
void floatPlanarToChar(float *src, unsigned char *dst, int height, int width,
int batchSize)
void floatPlanarToChar(float *src, unsigned char *dst, int height, int width, int batchSize)
{
floatToChar<<<(height * width - 1) / 1024 + 1, 1024, 0, NULL>>>(
src, dst, height, width, batchSize);
floatToChar<<<(height * width - 1) / 1024 + 1, 1024, 0, NULL>>>(src, dst, height, width, batchSize);
}
void dumpRawBGR(float *d_srcBGR, int pitch, int width, int height,
int batchSize, char *folder, char *tag)
void dumpRawBGR(float *d_srcBGR, int pitch, int width, int height, int batchSize, char *folder, char *tag)
{
float *bgr, *d_bgr;
int frameSize;
char directory[120];
char mkdir_cmd[256];
float *bgr, *d_bgr;
int frameSize;
char directory[120];
char mkdir_cmd[256];
#if !defined(_WIN32)
sprintf(directory, "output/%s", folder);
sprintf(mkdir_cmd, "mkdir -p %s 2> /dev/null", directory);
sprintf(directory, "output/%s", folder);
sprintf(mkdir_cmd, "mkdir -p %s 2> /dev/null", directory);
#else
sprintf(directory, "output\\%s", folder);
sprintf(mkdir_cmd, "mkdir %s 2> nul", directory);
sprintf(directory, "output\\%s", folder);
sprintf(mkdir_cmd, "mkdir %s 2> nul", directory);
#endif
int ret = system(mkdir_cmd);
int ret = system(mkdir_cmd);
frameSize = width * height * 3 * sizeof(float);
bgr = (float *)malloc(frameSize);
if (bgr == NULL)
{
std::cerr << "Failed malloc for bgr\n";
return;
}
d_bgr = d_srcBGR;
for (int i = 0; i < batchSize; i++)
{
char filename[256];
std::ofstream *outputFile;
checkCudaErrors(cudaMemcpy((void *)bgr, (void *)d_bgr, frameSize,
cudaMemcpyDeviceToHost));
snprintf(filename, sizeof(filename), "%s/%s_%d.raw", directory, tag, (i + 1));
outputFile = new std::ofstream(filename);
if (outputFile)
{
outputFile->write((char *)bgr, frameSize);
delete outputFile;
frameSize = width * height * 3 * sizeof(float);
bgr = (float *)malloc(frameSize);
if (bgr == NULL) {
std::cerr << "Failed malloc for bgr\n";
return;
}
d_bgr += pitch * height * 3;
}
d_bgr = d_srcBGR;
for (int i = 0; i < batchSize; i++) {
char filename[256];
std::ofstream *outputFile;
free(bgr);
checkCudaErrors(cudaMemcpy((void *)bgr, (void *)d_bgr, frameSize, cudaMemcpyDeviceToHost));
snprintf(filename, sizeof(filename), "%s/%s_%d.raw", directory, tag, (i + 1));
outputFile = new std::ofstream(filename);
if (outputFile) {
outputFile->write((char *)bgr, frameSize);
delete outputFile;
}
d_bgr += pitch * height * 3;
}
free(bgr);
}
void dumpBGR(float *d_srcBGR, int pitch, int width, int height, int batchSize,
char *folder, char *tag)
void dumpBGR(float *d_srcBGR, int pitch, int width, int height, int batchSize, char *folder, char *tag)
{
dumpRawBGR(d_srcBGR, pitch, width, height, batchSize, folder, tag);
dumpRawBGR(d_srcBGR, pitch, width, height, batchSize, folder, tag);
}
void dumpYUV(unsigned char *d_nv12, int size, char *folder, char *tag)
{
unsigned char *nv12Data;
std::ofstream *nv12File;
char filename[256];
char directory[60];
char mkdir_cmd[256];
unsigned char *nv12Data;
std::ofstream *nv12File;
char filename[256];
char directory[60];
char mkdir_cmd[256];
#if !defined(_WIN32)
sprintf(directory, "output/%s", folder);
sprintf(mkdir_cmd, "mkdir -p %s 2> /dev/null", directory);
sprintf(directory, "output/%s", folder);
sprintf(mkdir_cmd, "mkdir -p %s 2> /dev/null", directory);
#else
sprintf(directory, "output\\%s", folder);
sprintf(mkdir_cmd, "mkdir %s 2> nul", directory);
sprintf(directory, "output\\%s", folder);
sprintf(mkdir_cmd, "mkdir %s 2> nul", directory);
#endif
int ret = system(mkdir_cmd);
int ret = system(mkdir_cmd);
snprintf(filename, sizeof(filename), "%s/%s.nv12", directory, tag);
snprintf(filename, sizeof(filename), "%s/%s.nv12", directory, tag);
nv12File = new std::ofstream(filename);
if (nv12File == NULL)
{
std::cerr << "Failed to new " << filename;
return;
}
nv12File = new std::ofstream(filename);
if (nv12File == NULL) {
std::cerr << "Failed to new " << filename;
return;
}
nv12Data = (unsigned char *)malloc(size * (sizeof(char)));
if (nv12Data == NULL)
{
std::cerr << "Failed to allcoate memory\n";
return;
}
nv12Data = (unsigned char *)malloc(size * (sizeof(char)));
if (nv12Data == NULL) {
std::cerr << "Failed to allcoate memory\n";
return;
}
cudaMemcpy((void *)nv12Data, (void *)d_nv12, size, cudaMemcpyDeviceToHost);
cudaMemcpy((void *)nv12Data, (void *)d_nv12, size, cudaMemcpyDeviceToHost);
nv12File->write((const char *)nv12Data, size);
nv12File->write((const char *)nv12Data, size);
free(nv12Data);
delete nv12File;
free(nv12Data);
delete nv12File;
}

View File

@@ -29,9 +29,6 @@
#ifndef __H_UTIL_
#define __H_UTIL_
extern "C"
void dumpBGR(float *d_srcBGR, int pitch, int width, int height,
int batchSize, char *folder, char *tag);
extern "C"
void dumpYUV(unsigned char *d_nv12, int size, char *folder, char *tag);
extern "C" void dumpBGR(float *d_srcBGR, int pitch, int width, int height, int batchSize, char *folder, char *tag);
extern "C" void dumpYUV(unsigned char *d_nv12, int size, char *folder, char *tag);
#endif