#include "FFNvDecoderManager.h" #include #include "cuda_kernels.h" #include "NvJpegEncoder.h" #include #include #include unsigned char *pHwRgb = nullptr; /** * 注意: gpuFrame 在解码器设置的显卡上,后续操作要十分注意这一点,尤其是多线程情况 * */ void postDecoded(const void * userPtr, AVFrame * gpuFrame){ FFNvDecoder* decoder = (FFNvDecoder*)userPtr; if (decoder!= nullptr) { // cout << "decode name: " << decoder->getName() << endl; if (decoder->getName() == "dec1") { /* code */ } // const char* gpu_pixfmt = av_get_pix_fmt_name((AVPixelFormat)gpuFrame->format); // cout << "pixfmt: " << gpu_pixfmt << endl; // cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl; // cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl; if (gpuFrame->format == AV_PIX_FMT_CUDA) { // cout << "gpuid = " << atoi(decoder->m_cfg.gpuid.c_str()) << endl; // cudaSetDevice(atoi(decoder->m_cfg.gpuid.c_str())); // cudaError_t cudaStatus; // if(pHwRgb == nullptr){ // cuda_common::setColorSpace2( ITU709, 0 ); // cudaStatus = cudaMalloc((void **)&pHwRgb, 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char)); // } // cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], pHwRgb, gpuFrame->width, gpuFrame->height); // cudaDeviceSynchronize(); // if (cudaStatus != cudaSuccess) { // cout << "CUDAToBGR failed !!!" << endl; // return; // } // string path = "/home/cmhu/FFNvDecoder/" + decoder->m_cfg.gpuid + ".jpg"; // saveJpeg(path.c_str(), pHwRgb, gpuFrame->width, gpuFrame->height); // 验证 CUDAToRGB } } } long start_time = 0; long end_time = 0; bool count_flag = false; int count = 0; int count_std = 100; long long get_cur_time(){ // 获取操作系统当前时间点(精确到微秒) chrono::time_point tpMicro = chrono::time_point_cast(chrono::system_clock::now()); // (微秒精度的)时间点 => (微秒精度的)时间戳 time_t totalMicroSeconds = tpMicro.time_since_epoch().count(); long long currentTime = ((long long)totalMicroSeconds)/1000; return currentTime; } int sum = 0; void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ FFNvDecoder* decoder = (FFNvDecoder*)userPtr; if (decoder!= nullptr) { // cout << "decode name: " << decoder->getName() << endl; if (decoder->getName() == "dec") { if (! count_flag) { count_flag = true; count = 0; end_time = start_time = get_cur_time(); } count++; sum ++ ; if (count >= count_std) { end_time = get_cur_time(); long time_using = end_time - start_time; double time_per_frame = double(time_using)/count_std ; cout << count_std << "帧用时:" << time_using << "ms 每帧用时:" << time_per_frame << "ms" << endl; cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl; cout << gpuFrame->pts << endl; count_flag = false; } } } } // string test_uri = "rtmp://192.168.10.56:1935/objecteye/1"; string test_uri = "/home/cmhu/data/test.mp4"; void createDecode(int index){ FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); MgrDecConfig config; config.name = "dec" + to_string(index); config.cfg.uri = test_uri; config.cfg.post_decoded_cbk = postDecoded; config.cfg.force_tcp = true; if (index % 2 == 0) { config.cfg.gpuid = "2"; } else { config.cfg.gpuid = "1"; } FFNvDecoder* decoder = pDecManager->createDecoder(config); if (!decoder) { return ; } pDecManager->setUserPtr(config.name, decoder); pDecManager->startDecodeByName(config.name); } #define checkCudaErrors(S) do {CUresult status; \ status = S; \ if (status != CUDA_SUCCESS ) std::cout << __LINE__ <<" checkCudaErrors - status = " << status << std::endl; \ } while (false) int CheckCUDAProperty( int devId ) { cuInit(0); CUdevice dev = devId; size_t memSize = 0; char devName[256] = {0}; int major = 0, minor = 0; CUresult rlt = CUDA_SUCCESS; rlt = cuDeviceComputeCapability( &major, &minor, dev ); checkCudaErrors( rlt ); rlt = cuDeviceGetName( devName, sizeof( devName ), dev ); checkCudaErrors( rlt ); printf( "Using GPU Device %d: %s has SM %d.%d compute capability\n", dev, devName, major, minor ); rlt = cuDeviceTotalMem( &memSize, dev ); checkCudaErrors( rlt ); printf( "Total amount of global memory: %4.4f MB\n", (float)memSize / ( 1024 * 1024 ) ); return 0; } int main(){ CheckCUDAProperty(1); FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); int count = 105; for (size_t i = 0; i < count ; i++) { createDecode(i); } MgrDecConfig config; config.name = "dec"; config.cfg.uri = test_uri; config.cfg.post_decoded_cbk = postDecoded0; config.cfg.force_tcp = true; config.cfg.gpuid = "1"; FFNvDecoder* dec2 = pDecManager->createDecoder(config); if (!dec2) { return 1; } pDecManager->setUserPtr(config.name, dec2); pDecManager->startDecodeByName(config.name); pthread_t m_decode_thread; pthread_create(&m_decode_thread,0, [](void* arg) { while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(5000)); FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); int count = pDecManager->count(); cout << "当前运行路数: " << pDecManager->count() << endl; if (count <= 0) { break; } } return (void*)0; } ,nullptr); // config.name = "dec0"; // config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; // config.cfg.gpuid = "0"; // FFNvDecoder* dec0 = pDecManager->createDecoder(config); // if (!dec0) // { // return 1; // } // pDecManager->setUserPtr(config.name, dec0); // pDecManager->startDecodeByName(config.name); // config.name = "dec01"; // config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; // config.cfg.gpuid = "0"; // FFNvDecoder* dec01 = pDecManager->createDecoder(config); // if (!dec01) // { // return 1; // } // pDecManager->setUserPtr(config.name, dec01); // pDecManager->startDecodeByName(config.name); // while (getchar() != 'q'); // // pDecManager->closeDecoderByName("dec1"); // // pDecManager->pauseDecoder("dec1"); // pDecManager->pauseDecoder("dec2"); // while (getchar() != 'q'); // // pDecManager->resumeDecoder("dec1"); // pDecManager->resumeDecoder("dec2"); cout << "总共帧数:" << sum << endl; while (getchar() != 'q'); pDecManager->closeAllDecoder(); }