mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2026-10-26 06:38:16 +08:00
Apply consistent code formatting across the repo. Add clang-format and pre-commit hooks.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user