Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
AppDecD3D.cpp164 linesDownload Raw Back to AppDecD3D
1/*
2* Copyright 2017-2024 NVIDIA Corporation.  All rights reserved.
3*
4* Please refer to the NVIDIA end user license agreement (EULA) associated
5* with this source code for terms and conditions that govern your use of
6* this software. Any use, reproduction, disclosure, or distribution of
7* this software and related documentation outside the terms of the EULA
8* is strictly prohibited.
9*
10*/
11
12//---------------------------------------------------------------------------
13//! \file AppDecD3D.cpp
14//! \brief Source file for AppDecD3D sample
15//!
16//! This sample application illustrates the decoding of media file and display of decoded frames in a window.
17//! This is done by CUDA interop with D3D(both D3D9 and D3D11).
18//! For a detailed list of supported codecs on your NVIDIA GPU, refer : https://developer.nvidia.com/nvidia-video-codec-sdk#NVDECFeatures
19
20
21#include <cuda.h>
22#include <iostream>
23#include "NvDecoder/NvDecoder.h"
24#include "../Utils/NvCodecUtils.h"
25#include "../Utils/FFmpegDemuxer.h"
26#include "FramePresenterD3D9.h"
27#include "FramePresenterD3D11.h"
28#include "../Common/AppDecUtils.h"
29#include "../Utils/ColorSpace.h"
30
31simplelogger::Logger *logger = simplelogger::LoggerFactory::CreateConsoleLogger();
32
33/**
34*   @brief Function template to decode media file pointed to by szInFilePath parameter.
35           The decoded frames are displayed by using the D3D-CUDA interop.
36           In this app FramePresenterType is either FramePresenterD3D9 or FramePresenterD3D11.
37           The presentation rate is based on per frame time stamp.
38*   @param  cuContext - Handle to CUDA context
39*   @param  szInFilePath - Path to file to be decoded
40*   @return 0 on success
41*/
42template<class FramePresenterType, typename = std::enable_if<std::is_base_of<FramePresenterD3D, FramePresenterType>::value>>
43int NvDecD3D(CUcontext cuContext, char *szInFilePath)
44{
45    unsigned int timescale = 1000; // get timestamp in milisecond
46    FFmpegDemuxer demuxer(szInFilePath, timescale);
47    NvDecoder dec(cuContext, true, FFmpeg2NvCodecId(demuxer.GetVideoCodec()), false, false, NULL, NULL, false, 0, 0, timescale);
48    int nRGBWidth = (demuxer.GetWidth() + 1) & ~1;
49    FramePresenterType presenter(cuContext, nRGBWidth, demuxer.GetHeight());
50    CUdeviceptr dpFrame = 0;
51    ck(cuMemAlloc(&dpFrame, nRGBWidth * demuxer.GetHeight() * 4));
52    int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0;
53    uint8_t *pVideo = NULL, *pFrame;
54    int64_t pts, timestamp = 0;
55    bool m_bFirstFrame = true;
56    int64_t firstPts = 0, startTime = 0;
57    LARGE_INTEGER m_Freq;
58    int iMatrix = 0;
59
60    QueryPerformanceFrequency(&m_Freq);
61
62    do
63    {
64        demuxer.Demux(&pVideo, &nVideoBytes, &pts);
65        nFrameReturned = dec.Decode(pVideo, nVideoBytes, 0, pts);
66        if (!nFrame && nFrameReturned)
67            LOG(INFO) << dec.GetVideoInfo();
68
69        for (int i = 0; i < nFrameReturned; i++)
70        {
71            pFrame = dec.GetFrame(&timestamp);
72            iMatrix = dec.GetVideoFormatInfo().video_signal_description.matrix_coefficients;
73            if (dec.GetBitDepth() == 8)
74            {
75                 if (dec.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444)
76                    YUV444ToColor32<BGRA32>(pFrame, dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
77                else if (dec.GetOutputFormat() == cudaVideoSurfaceFormat_NV12)
78                    Nv12ToColor32<BGRA32>(pFrame, dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
79                else
80                    Nv16ToColor32<BGRA32>(pFrame, dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
81            }
82            else
83            {
84                if(dec.GetOutputFormat() == cudaVideoSurfaceFormat_YUV444_16Bit)
85                    YUV444P16ToColor32<BGRA32>(pFrame, 2 * dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
86                else if (dec.GetOutputFormat() == cudaVideoSurfaceFormat_P016)
87                    P016ToColor32<BGRA32>(pFrame, 2 * dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
88                else
89                    P216ToColor32<BGRA32>(pFrame, 2 * dec.GetWidth(), (uint8_t *)dpFrame, 4 * nRGBWidth, dec.GetWidth(), dec.GetHeight(), iMatrix);
90            }
91
92            LARGE_INTEGER counter;
93            if (m_bFirstFrame)
94            {
95                firstPts = timestamp;
96                QueryPerformanceCounter(&counter);
97                startTime = 1000 * counter.QuadPart / m_Freq.QuadPart;
98                m_bFirstFrame = false;
99            }
100
101            QueryPerformanceCounter(&counter);
102            int64_t curTime = timescale * counter.QuadPart / m_Freq.QuadPart;
103
104            int64_t expectedRenderTime = timestamp - firstPts + startTime;
105            int64_t delay = expectedRenderTime - curTime;
106            if (timestamp == 0)
107                delay = 0;
108            if (delay < 0)
109                continue;
110
111            presenter.PresentDeviceFrame((uint8_t *)dpFrame, nRGBWidth * 4, delay);
112        }
113        nFrame += nFrameReturned;
114    } while (nVideoBytes);
115    ck(cuMemFree(dpFrame));
116    std::cout << "Total frame decoded: " << nFrame << std::endl;
117    return 0;
118}
119
120int main(int argc, char **argv) 
121{
122    char szInFilePath[256] = "";
123    int iGpu = 0;
124    int iD3d = 0;
125    try
126    {
127        ParseCommandLine(argc, argv, szInFilePath, NULL, iGpu, NULL, &iD3d);
128        CheckInputFile(szInFilePath);
129
130        ck(cuInit(0));
131        int nGpu = 0;
132        ck(cuDeviceGetCount(&nGpu));
133        if (iGpu < 0 || iGpu >= nGpu)
134        {
135            std::ostringstream err;
136            err << "GPU ordinal out of range. Should be within [" << 0 << ", " << nGpu - 1 << "]" << std::endl;
137            throw std::invalid_argument(err.str());
138        }
139        CUdevice cuDevice = 0;
140        ck(cuDeviceGet(&cuDevice, iGpu));
141        char szDeviceName[80];
142        ck(cuDeviceGetName(szDeviceName, sizeof(szDeviceName), cuDevice));
143        std::cout << "GPU in use: " << szDeviceName << std::endl;
144        CUcontext cuContext = NULL;
145        ck(NVCODEC_CUDA_CTX_CREATE(&cuContext, CU_CTX_SCHED_BLOCKING_SYNC, cuDevice));
146
147        switch (iD3d) {
148        default:
149        case 9:
150            std::cout << "Display with D3D9." << std::endl;
151            return NvDecD3D<FramePresenterD3D9>(cuContext, szInFilePath);
152        case 11:
153            std::cout << "Display with D3D11." << std::endl;
154            return NvDecD3D<FramePresenterD3D11>(cuContext, szInFilePath);
155        }
156    }
157    catch (const std::exception& ex)
158    {
159        std::cout << ex.what();
160        exit(1);
161    }
162    return 0;
163}
164 
codekingpro/portable-devtools · Team Ai