/*
* Copyright 1993-2015 NVIDIA Corporation. All rights reserved.
*
* Please refer to the NVIDIA end user license agreement (EULA) associated
* with this source code for terms and conditions that govern your use of
* this software. Any use, reproduction, disclosure, or distribution of
* this software and related documentation outside the terms of the EULA
* is strictly prohibited.
*
*/
/* This example demonstrates how to use the Video Decode Library with CUDA
* bindings to interop between NVDECODE(using CUDA surfaces) and DX9 textures.
* Post-Process video (de-interlacing) is suported with this sample.
*/
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#pragma comment(lib, "version.lib")
#endif
#include "d3d9.h"
#include "d3dx9.h"
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// CUDA Header includes
#include "dynlink_nvcuvid.h" // <nvcuvid.h>
#include "dynlink_cuda.h" // <cuda.h>
#include "dynlink_cudaD3D9.h" // <cudaD3D9.h>
#include "dynlink_builtin_types.h" // <builtin_types.h>
// CUDA utilities and system includes
#include "helper_functions.h"
#include "helper_cuda_drvapi.h"
// cudaDecodeD3D9 related helper functions
#include "FrameQueue.h"
#include "VideoSource.h"
#include "VideoParser.h"
#include "VideoDecoder.h"
#include "ImageDX.h"
#include "cudaProcessFrame.h"
#include "cudaModuleMgr.h"
// Include files
#include <math.h>
#include <memory>
#include <iostream>
#include <cassert>
const char *sAppName = "NVDECODE/D3D9 Video Decoder";
const char *sAppFilename = "NVDecodeD3D9";
const char *sSDKname = "NVDecodeD3D9";
#ifdef _DEBUG
#define ENABLE_DEBUG_OUT 0
#else
#define ENABLE_DEBUG_OUT 0
#endif
StopWatchInterface *frame_timer = NULL;
StopWatchInterface *global_timer = NULL;
int g_DeviceID = 0;
bool g_bWindowed = true;
bool g_bDeviceLost = false;
bool g_bDone = false;
bool g_bRunning = false;
bool g_bAutoQuit = false;
bool g_bUseVsync = false;
bool g_bFrameRepeat= false;
bool g_bFrameStep = false;
bool g_bQAReadback = false;
bool g_bFirstFrame = true;
bool g_bLoop = false;
bool g_bUpdateCSC = true;
bool g_bUpdateAll = false;
bool g_bUseDisplay = true; // this flag enables/disables video on the window
bool g_bUseInterop = true;
bool g_bReadback = false; // this flag enables/disables reading back of a video from a window
bool g_bWriteFile = false; // this flag enables/disables writing of a file
bool g_bPSNR = false; // if this flag is set true, then we want to compute the PSNR
bool g_bIsProgressive = true; // assume it is progressive, unless otherwise noted
bool g_bException = false;
bool g_bWaived = false;
int g_iRepeatFactor = 1; // 1:1 assumes no frame repeats
long g_nFrameStart = -1;
long g_nFrameEnd = -1;
int *pArgc = NULL;
char **pArgv = NULL;
FILE *fpWriteYUV = NULL;
FILE *fpRefYUV = NULL;
cudaVideoCreateFlags g_eVideoCreateFlags = cudaVideoCreate_Default;
CUvideoctxlock g_CtxLock = NULL;
float present_fps, decoded_fps, total_time = 0.0f;
D3DDISPLAYMODE g_d3ddm;
D3DPRESENT_PARAMETERS g_d3dpp;
IDirect3D9 *g_pD3D; // Used to create the D3DDevice
IDirect3DDevice9 *g_pD3DDevice;
// These are CUDA function pointers to the CUDA kernels
CUmoduleManager *g_pCudaModule;
CUmodule cuModNV12toARGB = 0;
CUfunction g_kernelNV12toARGB = 0;
CUfunction g_kernelPassThru = 0;
CUcontext g_oContext = 0;
CUdevice g_oDevice = 0;
CUstream g_ReadbackSID = 0, g_KernelSID = 0;
eColorSpace g_eColorSpace = ITU601;
float g_nHue = 0.0f;
// System Memory surface we want to readback to
BYTE *g_pFrameYUV[6] = { 0, 0, 0, 0, 0, 0 };
FrameQueue *g_pFrameQueue = 0;
VideoSource *g_pVideoSource = 0;
VideoParser *g_pVideoParser = 0;
VideoDecoder *g_pVideoDecoder = 0;
ImageDX *g_pImageDX = 0;
CUdeviceptr g_pInteropFrame[3] = { 0, 0, 0 }; // if we're using CUDA malloc
CUVIDEOFORMAT g_stFormat;
std::string sFileName;
char exec_path[256];
unsigned int g_nWindowWidth = 0;
unsigned int g_nWindowHeight = 0;
unsigned int g_nVideoWidth = 0;
unsigned int g_nVideoHeight = 0;
unsigned int g_FrameCount = 0;
unsigned int g_DecodeFrameCount = 0;
unsigned int g_fpsCount = 0; // FPS count for averaging
unsigned int g_fpsLimit = 500; // FPS limit for sampling timer;
// Forward declarations
bool initD3D9(HWND hWnd, int argc, char **argv, int *pbTCC);
HRESULT initD3D9Surface(unsigned int nWidth, unsigned int nHeight);
HRESULT freeDestSurface();
bool loadVideoSource(const char *video_file,
unsigned int &width, unsigned int &height,
unsigned int &dispWidth, unsigned int &dispHeight);
void initCudaVideo();
void freeCudaResources(bool bDestroyContext);
bool copyDecodedFrameToTexture(unsigned int &nRepeats, int bUseInterop, int *pbIsProgressive);
void cudaPostProcessFrame(CUdeviceptr *ppDecodedFrame, size_t nDecodedPitch,
CUdeviceptr *ppTextureData, size_t nTexturePitch,
CUmodule cuModNV12toARGB,
CUfunction fpCudaKernel, CUstream streamID);
HRESULT drawScene(int field_num);
HRESULT cleanup(bool bDestroyContext);
HRESULT initCudaResources(int argc, char **argv, int bUseInterop, int bTCC);
void renderVideoFrame(HWND hWnd, bool bUseInterop);
#ifndef STRCASECMP
#define STRCASECMP _stricmp
#endif
#ifndef STRNCASECMP
#define STRNCASECMP _strnicmp
#endif
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool checkHW(char *name, char *gpuType, int dev)
{
char deviceName[256];
checkCudaErrors(cuDeviceGetName(deviceName, 256, dev));
STRCPY(name, strlen(deviceName), deviceName);
if (!strnicmp(deviceName, gpuType, strlen(gpuType)))
{
return true;
}
else
{
return false;
}
}
unsigned int GetOSVersion()
{
const char* kernel32 = "kernel32.dll";
char path[MAX_PATH];
UINT n = GetSystemDirectory(path, MAX_PATH);
if (n > MAX_PATH - strlen(kernel32)) {
return 0xffffffff;
}
sprintf_s(path, "%s\\%s", path, kernel32);
DWORD versionSize = GetFileVersionInfoSize(path, NULL);
if (!versionSize) {
return 0xffffffff;
}
BYTE* version = new BYTE[versionSize];
BOOL ret = GetFileVersionInfo(path, 0, versionSize, (void*)version);
if (!ret) {
delete[] version;
return 0xffffffff;
}
BYTE* buffer = NULL;
UINT bufferSize = 0;
ret = VerQueryValue(version, "\\", (void**)&buffer, &bufferSize);
if (!ret || bufferSize < sizeof(VS_FIXEDFILEINFO)) {
delete[] version;
return 0xffffffff;
}
VS_FIXEDFILEINFO *vinfo = (VS_FIXEDFILEINFO*)buffer;
int verOS = HIWORD(vinfo->dwProductVersionMS);
delete[] version;
return verOS;
}
void printStatistics()
{
int hh, mm, ss, msec;
present_fps = 1.f / (total_time / (g_FrameCount * 1000.f));
decoded_fps = 1.f / (total_time / (g_DecodeFrameCount * 1000.f));
msec = ((int)total_time % 1000);
ss = (int)(total_time/1000) % 60;
mm = (int)(total_time/(1000*60)) % 60;
hh = (int)(total_time/(1000*60*60)) % 60;
print
- 1
- 2
- 3
- 4
- 5
前往页