diff --git a/.vscode/launch.json b/.vscode/launch.json index 8f90775..51b59bd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/bin/lib/test", - "args": [], + "args": ["rtsp://176.10.0.4:8554/stream","0"], "stopAtEntry": false, "cwd": "${workspaceFolder}/bin/lib", "environment": [], diff --git a/.vscode/settings.json b/.vscode/settings.json index 7cfc35b..b797d5c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,57 @@ "iostream": "cpp", "thread": "cpp", "nvdec.h": "c", - "chrono": "cpp" + "chrono": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cfenv": "cpp", + "cinttypes": "cpp", + "__nullptr": "cpp" } } \ No newline at end of file diff --git a/src/FFCuContextManager.cpp b/src/FFCuContextManager.cpp index 169cf29..8f5b09a 100644 --- a/src/FFCuContextManager.cpp +++ b/src/FFCuContextManager.cpp @@ -19,7 +19,7 @@ AVBufferRef *FFCuContextManager::getCuCtx(string gpuid) // 初始化硬件解码器 if (av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, gpuid.c_str(), nullptr, 0) < 0) { - cout << "Failed to create specified HW device."; + av_log(nullptr, AV_LOG_ERROR, "Failed to create specified HW device ! \n"); return nullptr; } ctxMap[gpuid] = hw_device_ctx; diff --git a/src/FFNvDecoder.cpp b/src/FFNvDecoder.cpp index e89e99e..657f46b 100644 --- a/src/FFNvDecoder.cpp +++ b/src/FFNvDecoder.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include "FFCuContextManager.h" using namespace std; @@ -23,7 +21,7 @@ static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *p return *p; } - av_log(NULL, AV_LOG_ERROR, "Failed to get HW surface format. \n"); + av_log(nullptr, AV_LOG_ERROR, "Failed to get HW surface format. \n"); return AV_PIX_FMT_NONE; } @@ -85,13 +83,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) fmt_ctx = avformat_alloc_context(); const char* input_file = uri; if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open input file: %s \n", input_file); + av_log(nullptr, AV_LOG_ERROR, "Cannot open input file: %s \n", input_file); return false; } // 查找流信息 if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find input stream information ! \n"); + av_log(nullptr, AV_LOG_ERROR, "Cannot find input stream information ! \n"); return false; } @@ -99,7 +97,7 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) AVCodec *decoder = nullptr; stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); if (stream_index < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); + av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); return false; } @@ -120,7 +118,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) hw_pix_fmt = AV_PIX_FMT_CUDA; FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance(); - avctx->hw_device_ctx = av_buffer_ref(pCtxMgr->getCuCtx(gpuid)); + + AVBufferRef *hw_device_ctx = pCtxMgr->getCuCtx(gpuid); + if(nullptr == hw_device_ctx){ + av_log(nullptr, AV_LOG_ERROR, "create CUDA context failed ! \n"); + return false; + } + avctx->hw_device_ctx = av_buffer_ref(hw_device_ctx); if (nullptr == avctx->hw_device_ctx) { return false; @@ -129,9 +133,9 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) // 打开解码器流 AVDictionary *op = nullptr; av_dict_set( &op, "gpu", gpuid, 0 ); - av_dict_set( &op, "surfaces", "10", 0 ); + // av_dict_set( &op, "surfaces", "10", 0 ); if (avcodec_open2(avctx, vcodec, &op) < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to open codec for stream ! \n"); + av_log(nullptr, AV_LOG_ERROR, "Failed to open codec for stream ! \n"); return false; } @@ -161,14 +165,12 @@ void FFNvDecoder::start(){ static long long get_cur_time(){ // 获取操作系统当前时间点(精确到微秒) - chrono::time_point tpMicro - = chrono::time_point_cast(chrono::system_clock::now()); + chrono::time_point tpMicro + = chrono::time_point_cast(chrono::system_clock::now()); // (微秒精度的)时间点 => (微秒精度的)时间戳 - time_t totalMicroSeconds = tpMicro.time_since_epoch().count(); + time_t currentTime = tpMicro.time_since_epoch().count(); - long long currentTime = ((long long)totalMicroSeconds)/1000; - - return currentTime; + return (long long )currentTime; } void FFNvDecoder::decode_thread() @@ -209,7 +211,7 @@ void FFNvDecoder::decode_thread() int result = av_read_frame(fmt_ctx, pkt); if (result == AVERROR_EOF || result < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to read frame! \n"); + av_log(nullptr, AV_LOG_ERROR, "Failed to read frame! \n"); break; } @@ -231,13 +233,13 @@ void FFNvDecoder::decode_thread() if (stream_index == pkt->stream_index){ result = avcodec_send_packet(avctx, pkt); if (result < 0){ - av_log(NULL, AV_LOG_ERROR, "Failed to send pkt: %d \n",result); + av_log(nullptr, AV_LOG_ERROR, "Failed to send pkt: %d \n",result); continue; } result = avcodec_receive_frame(avctx, gpuFrame); if ((result == AVERROR(EAGAIN) || result == AVERROR_EOF) || result < 0){ - av_log(NULL, AV_LOG_ERROR, "Failed to receive frame: %d \n",result); + av_log(nullptr, AV_LOG_ERROR, "Failed to receive frame: %d \n",result); continue; } @@ -269,7 +271,7 @@ void FFNvDecoder::decode_thread() decode_finished(); - av_log(NULL, AV_LOG_INFO, "decode thread exited. \n"); + av_log(nullptr, AV_LOG_INFO, "decode thread exited. \n"); } void FFNvDecoder::decode_finished() @@ -304,7 +306,7 @@ void FFNvDecoder::post_decode_thread() mFrameQueue.addHead(); } - av_log(NULL, AV_LOG_INFO, "post decode thread exited. \n"); + av_log(nullptr, AV_LOG_INFO, "post decode thread exited. \n"); } void FFNvDecoder::close() @@ -345,10 +347,10 @@ bool FFNvDecoder::isPausing(){ bool FFNvDecoder::getResolution( int &width, int &height ) { - if (avctx != nullptr) + if (stream != nullptr && stream->codecpar != nullptr) { - width = avctx->width; - height = avctx->height; + width = stream->codecpar->width; + height = stream->codecpar->height; return true; } @@ -376,7 +378,7 @@ int FFNvDecoder::getCachedQueueLength(){ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ - AVFormatContext* ifmt_ctx = NULL; + AVFormatContext* ifmt_ctx = nullptr; AVCodecContext* codec_ctx = nullptr; AVCodec* codec = nullptr; AVPacket* pkt = nullptr; @@ -385,36 +387,44 @@ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ int video_index = -1; AVStream* st = nullptr; SwsContext *img_convert_ctx = nullptr; - uint8_t *buffer = NULL; + uint8_t *buffer = nullptr; int numBytes = 0; FFImgInfo* imgInfo = nullptr; - - //av_register_all(); + + avformat_network_init(); + // 打开输入视频文件 + AVDictionary *options = nullptr; + av_dict_set( &options, "bufsize", "655360", 0 ); + av_dict_set( &options, "rtsp_transport", "tcp", 0 ); + // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s + av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 + ///打开输入的流 - int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), NULL, NULL); + ifmt_ctx = avformat_alloc_context(); + int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options); if (ret != 0){ - av_log(NULL, AV_LOG_ERROR, "Couldn't open input stream ! \n"); + av_log(nullptr, AV_LOG_ERROR, "Couldn't open input stream ! \n"); goto end_flag ; } //查找流信息 - if (avformat_find_stream_info(ifmt_ctx, NULL) < 0){ - av_log(NULL, AV_LOG_ERROR, "Couldn't find stream information ! \n"); + if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){ + av_log(nullptr, AV_LOG_ERROR, "Couldn't find stream information ! \n"); goto end_flag ; } //找到视频流索引 - video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); + video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0); st = ifmt_ctx->streams[video_index]; //找到解码器 codec = avcodec_find_decoder(st->codecpar->codec_id); if (!codec){ - av_log(NULL, AV_LOG_ERROR, "Codec not found ! \n"); + av_log(nullptr, AV_LOG_ERROR, "Codec not found ! \n"); goto end_flag ; } @@ -427,7 +437,7 @@ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ avcodec_parameters_to_context(codec_ctx, ifmt_ctx->streams[video_index]->codecpar); //打开解码器 - if ((ret = avcodec_open2(codec_ctx, codec, NULL) < 0)){ + if ((ret = avcodec_open2(codec_ctx, codec, nullptr) < 0)){ goto end_flag ; } @@ -439,7 +449,7 @@ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_BGR24, codec_ctx->width, codec_ctx->height, 1); img_convert_ctx = sws_getContext(codec_ctx->width, codec_ctx->height,codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_BGR24, - SWS_BICUBIC, NULL, NULL, NULL); + SWS_BICUBIC, nullptr, nullptr, nullptr); pkt = av_packet_alloc(); frame = av_frame_alloc(); @@ -449,7 +459,8 @@ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ if (ret >= 0){ ret = avcodec_receive_frame(codec_ctx, frame); if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ - av_log(NULL, AV_LOG_ERROR, "Failed to receive frame: %d \n", ret); + av_log(nullptr, AV_LOG_ERROR, "Failed to receive frame: %d \n", ret); + av_packet_unref(pkt); continue; } @@ -459,10 +470,11 @@ FFImgInfo* FFNvDecoder::snapshot(const string& uri){ imgInfo->pData = buffer; imgInfo->height = codec_ctx->height; imgInfo->width = codec_ctx->width; - break; } } + + av_packet_unref(pkt); } end_flag: @@ -499,4 +511,4 @@ void FFNvDecoder::releaseFFImgInfo(FFImgInfo* info){ delete info; info = nullptr; } -} \ No newline at end of file +} diff --git a/src/Makefile b/src/Makefile index f21a11b..f5ae7f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,9 +2,6 @@ XX = g++ NVCC = nvcc - -DEFS= -DPOST_USE_RABBITMQ - PROJECT_ROOT= /mnt/e/fiss/FFNvDecoder DEPEND_DIR = $(PROJECT_ROOT)/bin @@ -24,10 +21,10 @@ LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilte -L $(CUDA_ROOT)/lib64 -lcudart -lcurand -lcublas -lnvjpeg \ -L /usr/lib/wsl/lib -lcuda -lnvcuvid\ -CFLAGS= -g -fPIC -O0 $(DEFS) $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl +CFLAGS= -g -fPIC -O0 $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl # -DUNICODE -D_UNICODE -NFLAGS_LIB=-g -c $(DEFS) -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden +NFLAGS_LIB=-g -c -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden NFLAGS = $(NFLAGS_LIB) $(INCLUDE) -std=c++11 SRCS:=$(wildcard $(SRC_ROOT)/*.cpp) diff --git a/src/common/inc/helper_cuda_drvapi.h b/src/common/inc/helper_cuda_drvapi.h index 76eacb5..ffca8e8 100644 --- a/src/common/inc/helper_cuda_drvapi.h +++ b/src/common/inc/helper_cuda_drvapi.h @@ -218,7 +218,8 @@ inline int gpuGetMaxGflopsDeviceIdDRV() // Find the best major SM Architecture GPU device while (current_device < device_count) { - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device)); + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device)); if (major > 0 && major < 9999) { @@ -239,7 +240,9 @@ inline int gpuGetMaxGflopsDeviceIdDRV() checkCudaErrors(cuDeviceGetAttribute(&clockRate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, current_device)); - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device)); + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device)); int computeMode; getCudaAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device); @@ -317,7 +320,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV() while (current_device < device_count) { checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device)); - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device)); + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device)); #if CUDA_VERSION >= 3020 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); @@ -369,7 +374,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV() checkCudaErrors(cuDeviceGetAttribute(&clockRate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, current_device)); - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device)); + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device)); #if CUDA_VERSION >= 3020 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); @@ -500,7 +507,9 @@ inline bool checkCudaCapabilitiesDRV(int major_version, int minor_version, int d checkCudaErrors(cuDeviceGet(&cuDevice, devID)); checkCudaErrors(cuDeviceGetName(name, 100, cuDevice)); - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, devID)); + + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, devID)); + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, devID)); if ((major > major_version) || (major == major_version && minor >= minor_version)) diff --git a/src/main.cpp b/src/main.cpp index 1d08668..7347f97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -164,7 +164,8 @@ void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ // string test_uri = "/home/cmhu/data/output_800x480.mp4"; // string test_uri = "/home/cmhu/data/output_1920x1080.mp4"; // string test_uri = "rtsp://176.10.0.2:8554/stream"; -string test_uri = "/mnt/f/fiss/test_data/h265.mp4"; +// string test_uri = "/mnt/f/fiss/test_data/h265.mp4"; +string test_uri = "rtsp://176.10.0.4:8554/stream"; void createDecode(int index){ FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); @@ -207,7 +208,10 @@ int CheckCUDAProperty( int devId ) int major = 0, minor = 0; CUresult rlt = CUDA_SUCCESS; - rlt = cuDeviceComputeCapability( &major, &minor, dev ); + rlt = cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, dev); + checkCudaErrors( rlt ); + + rlt = cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, dev); checkCudaErrors( rlt ); rlt = cuDeviceGetName( devName, sizeof( devName ), dev ); @@ -260,6 +264,10 @@ int main(){ // pDecManager->setDecKeyframe(config.name, true); pDecManager->startDecodeByName(config.name); + int w,h; + pDecManager->getResolution(config.name, w,h); + printf( "%s : %dx%d\n", config.name.c_str() , w,h ); + pthread_t m_decode_thread; pthread_create(&m_decode_thread,0, [](void* arg)