ffmpeg+D3D实现的MFC音视频播放器,支持录像、截图、音视频播放、码流信息显示等功能

一、简介

    本播放器是在vs2019下开发,通过ffmpeg实现拉流解码功能,通过D3D实现视频的渲染功能。截图功能采用libjpeg实现,可以截取jpg图片,图片的默认保存路径是在C:\MYRecPath中。录像功能采用封装好的类Mp4Record实现,在Mp4Record类中主要还是采用ffmpeg的相关函数方法进行mp4视频的录制。音频的播放采用DirectSound实现,将ffmpeg解码后的音频数据存储到DirectSound的buffer中,再调用DirectSound的play实现对音频的播放功能。码流信息的显示,通过D3D的文本绘制实现。本播放器提供源码下载,直接下载请点击最后的下载链接。

二、界面展示

在这里插入图片描述

三、相关代码

开始播放

int CVideoPlayer::StartPlay(const char* sUrl)
{m_bStop = false;m_nVideoIndex = -1;m_nAudioIndex = -1;int i = 0, res = 0,  nValue = 0;char buf[64] = { 0 };m_bPlaying = false;AVStream* in_stream;_snprintf_s(m_sConnectUrl, sizeof(m_sConnectUrl), sizeof(m_sConnectUrl) - 1, "%s", sUrl);//av_register_all();avformat_network_init();AVDictionary* optionsDict = nullptr;av_dict_set(&optionsDict, "rtsp_transport", "tcp", 0);av_dict_set(&optionsDict, "stimeout", "5000000", 0);av_dict_set(&optionsDict, "buffer_size", "8192000", 0);av_dict_set(&optionsDict, "recv_buffer_size", "8192000", 0);m_lastReadPacktTime = av_gettime();m_pAVFmtCxt = avformat_alloc_context();m_pAVFmtCxt->interrupt_callback.opaque = this;m_pAVFmtCxt->interrupt_callback.callback = decodeInterruptCb;res = avformat_open_input(&m_pAVFmtCxt, m_sConnectUrl, NULL, &optionsDict);if (res < 0){myprint("avformat_open_input fail: %d", res);return -1;}if (!m_pAVFmtCxt){return -1;}m_pAVFmtCxt->probesize = 100 * 1024;    m_pAVFmtCxt->max_analyze_duration = 1 * AV_TIME_BASE; res = avformat_find_stream_info(m_pAVFmtCxt, NULL);if (res < 0){myprint("error %x in avformat_find_stream_info\n", res);return -1;}av_dump_format(m_pAVFmtCxt, 0, m_sConnectUrl, 0);for (i = 0; i < m_pAVFmtCxt->nb_streams; i++){if (m_pAVFmtCxt->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){m_nVideoIndex = i;}else if (m_pAVFmtCxt->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {m_nAudioIndex = i;}myprint("m_pAVFmtCxt->streams[i]->codec->codec_type:%d", m_pAVFmtCxt->streams[i]->codecpar->codec_type);}//videoindex not findif (m_nVideoIndex == -1){myprint("can't find video stream.");return -1;}m_pCodec = avcodec_find_decoder(m_pAVFmtCxt->streams[m_nVideoIndex]->codecpar->codec_id);if (!m_pCodec){myprint("video decoder not found\n");return -1;}if (m_bSupportAudio && m_nAudioIndex != -1){myprint("start audio decoder \n");if (!m_pAudioCodecCxt)m_pAudioCodecCxt = avcodec_alloc_context3(NULL);auto pAudioCodecpar = m_pAVFmtCxt->streams[m_nAudioIndex]->codecpar;avcodec_parameters_to_context(m_pAudioCodecCxt, pAudioCodecpar);m_pAudioCodec = avcodec_find_decoder(pAudioCodecpar->codec_id);if (nullptr == m_pAudioCodec || nullptr == m_pAudioCodecCxt){myprint("audio decoder not found\n");return -1;}m_pSwrContext = swr_alloc_set_opts(0,                                 av_get_default_channel_layout(m_channels_play),AV_SAMPLE_FMT_S16,                         m_nSampleRate,                     av_get_default_channel_layout(m_pAudioCodecCxt->channels),m_pAudioCodecCxt->sample_fmt,       m_pAudioCodecCxt->sample_rate,      0,0);auto ret = swr_init(m_pSwrContext);if (ret < 0){myprint("Failed to swr_init(pSwrContext);");return -1;}if (InitDirectSound() == FALSE)m_bSupportAudio = false;}m_CodecId = m_pCodec->id;if(!m_pCodecCxt)m_pCodecCxt = avcodec_alloc_context3(NULL);avcodec_parameters_to_context(m_pCodecCxt, m_pAVFmtCxt->streams[m_nVideoIndex]->codecpar);if (m_pCodecCxt){if (m_pCodecCxt->width == 0 || m_pCodecCxt->height == 0){myprint("m_pCodecCxt->width:%d, m_pCodecCxt->height:%d", m_pCodecCxt->width, m_pCodecCxt->height);return -1;}}elsereturn -1;AVCodecContext* temp_codecctx = m_pCodecCxt;memcpy(temp_codecctx, m_pCodecCxt, sizeof(m_pCodecCxt));if (m_pCodecCxt->codec_type == AVMEDIA_TYPE_VIDEO){myprint("Soft Solution");avcodec_close(m_pCodecCxt);m_pCodecCxt = temp_codecctx;m_pCodecCxt->thread_count = 4;if (m_Dxva2D3DRender.InitD3DRender(m_showWnd, m_pCodecCxt->width, m_pCodecCxt->height) == false){myprint("InitD3DRender fail");}m_pOutBuffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, m_pCodecCxt->width, m_pCodecCxt->height, 1));if (nullptr == m_pOutBuffer)return -1;av_image_fill_arrays(m_pFrameBGR->data, m_pFrameBGR->linesize, m_pOutBuffer, AV_PIX_FMT_YUV420P, m_pCodecCxt->width, m_pCodecCxt->height, 1); //填充AVFrame数据缓冲m_pImgConvertCtx = sws_getContext(m_pCodecCxt->width, m_pCodecCxt->height, m_pCodecCxt->pix_fmt, m_pCodecCxt->width, m_pCodecCxt->height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);if (nullptr == m_pImgConvertCtx)return -1;m_nActualWidth = m_pCodecCxt->width;m_nActualHeight = m_pCodecCxt->height;res = avcodec_open2(m_pCodecCxt, m_pCodec, NULL);if (res < 0){myprint("avcodec_open2 video fail  error:%x", res);return -1;}}if (m_bSupportAudio && m_pAudioCodecCxt){if (m_pAudioCodecCxt->codec_type == AVMEDIA_TYPE_AUDIO){res = avcodec_open2(m_pAudioCodecCxt, m_pAudioCodec, NULL);if (res < 0){myprint("avcodec_open2 audio fail  error:%x", res);avcodec_close(m_pAudioCodecCxt);return -1;}myprint("===Audio Message===");myprint(" bit_rate = %d ", m_pAudioCodecCxt->bit_rate);myprint(" sample_rate = %d ", m_pAudioCodecCxt->sample_rate);myprint(" channels = %d ", m_pAudioCodecCxt->channels);myprint(" code_name = %s ", m_pAudioCodecCxt->codec->name);myprint(" block_align = %d ", m_pAudioCodecCxt->block_align);}}m_pDecodeThread = (my_thread_t*)my_malloc(sizeof(my_thread_t));if (nullptr != m_pDecodeThread){m_bDecodeThreadRun = true;res = my_thread_create(m_pDecodeThread, ThreadDecode, this);if (res == -1){myprint("my_thread_create ThreadDecode failed  res:%x", res);return -1;}}return 0;
}

停止播放

void CVideoPlayer::StopPlay()
{m_bPlaying = false;m_CaptureAudio.SetGrabAudioFrames(FALSE, NULL);m_CaptureAudio.Close();m_bStopAudio = true;while (!m_AudioPlayQue.empty()){m_AudioPlayQue.pop();}while (!m_AudioTalkQue.empty()){EnterCriticalSection(&m_talklock);m_AudioTalkQue.pop();LeaveCriticalSection(&m_talklock);}m_bDecodeThreadRun = false;if (m_pDecodeThread){my_thread_join(m_pDecodeThread);my_free(m_pDecodeThread);m_pDecodeThread = nullptr;}if (m_pAudioPlayThread) {SetEvent(m_event);if (m_pAudioPlayThread->handle) {my_thread_join(m_pAudioPlayThread);m_pAudioPlayThread->handle = nullptr;}}if (m_pDSBuffer8){m_pDSBuffer8->Stop();m_pDSBuffer8->Restore();}m_Dxva2D3DRender.UnitD3DRender();if (m_pCodecCxt){avcodec_close(m_pCodecCxt);}if (m_pAudioCodecCxt){avcodec_close(m_pAudioCodecCxt);}if (m_pSwrContext){swr_free(&m_pSwrContext);m_pSwrContext = nullptr;}if (m_pAVFmtCxt) {avformat_close_input(&m_pAVFmtCxt);avformat_free_context(m_pAVFmtCxt);m_pAVFmtCxt = nullptr;}}

解码线程

void CVideoPlayer::DecodeAndShow()
{if (m_pAVFmtCxt == nullptr || m_pCodecCxt == nullptr)return;AVPacket pkt = { 0 };m_bPlaying = true;uint8_t* pBuffer;bool bEnoughSpace = true;int nTimeCnt = 0;int res = 0;struct SwsContext* img_convert_ctx = nullptr;int nRectDrawWait = 0;bool bRecordLastIFrame = false;int num_av_read_frame_err = 0;int num_stream_index_err = 0;uint8_t * outData[2] = {0};outData[0] = (uint8_t*)av_malloc(1152 * 8);outData[1] = (uint8_t*)av_malloc(1152 * 8);uint8_t* pktdata;int pktsize;int len = 0;bool bPushAudioToQueue = false;m_bStopAudio = false;CRect ShowRect;AVFrame* pAvFrame = av_frame_alloc();if (nullptr == pAvFrame)return;AVFrame* pFrameRGB = av_frame_alloc();if (nullptr == pFrameRGB)return;int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, m_pCodecCxt->width, m_pCodecCxt->height, 1);pBuffer = (uint8_t*)av_malloc(numBytes);if (nullptr == pBuffer)return;av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize, pBuffer, AV_PIX_FMT_RGB24, m_pCodecCxt->width, m_pCodecCxt->height, 1);img_convert_ctx = sws_getCachedContext(img_convert_ctx, m_pCodecCxt->width, m_pCodecCxt->height,m_pCodecCxt->pix_fmt, m_pCodecCxt->width, m_pCodecCxt->height, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR/*SWS_BICUBIC*/, NULL, NULL, NULL);//Audioif (m_bSupportAudio && m_pAudioPlayThread){res = my_thread_create(m_pAudioPlayThread, ThreadAudioPlay, this);if (res < 0)myprint("my_thread_create ThreadAudioPlay fail");}while (m_bDecodeThreadRun && !m_bQuit){if (m_bPause){Sleep(100);continue;}{if (m_bReconnect){myprint("bReConnect = true, break");break;}}m_lastReadPacktTime = av_gettime();if (av_read_frame(m_pAVFmtCxt, &pkt) >= 0){num_av_read_frame_err = 0;if (pkt.stream_index == m_nVideoIndex || pkt.stream_index == m_nAudioIndex){if (m_bRecord)//Record{if (nTimeCnt != 0 || (!bRecordLastIFrame && pkt.flags == AV_PKT_FLAG_KEY)) {if (m_sRecPath[0] != '\0' && nTimeCnt++ % 200 == 0){bEnoughSpace = CheckRemainSpace(m_sRecPath);if (bEnoughSpace == true){myprint("bEnoughSpace = true");}elsemyprint("bEnoughSpace = false");}m_nRecordCurrentTime = time(NULL);if ((m_nRecordCurrentTime - m_nRecordStartTime) >= (m_nRecordTime * 60)){myprint("Record Finsh!");stopRecord();}else if (bEnoughSpace == false){myprint("bEnoughSpace == false");stopRecord();}else{AVPacket* pPkt = av_packet_clone(&pkt);m_mp4Recorder.saveOneFrame(*pPkt, m_CodecId);av_packet_free(&pPkt);}}bRecordLastIFrame = pkt.flags == AV_PKT_FLAG_KEY;}elsenTimeCnt = 0;}if (pkt.stream_index == m_nVideoIndex){num_stream_index_err = 0;nTimeCnt = 0;if (pkt.flags == 1)bPushAudioToQueue = true;if (nullptr == m_pCodecCxt || nullptr == pAvFrame) {myprint("m_pCodecCxt == NULL || pAvFrame == NULL");break;}int gotvframe = 0;auto sd_ret = avcodec_send_packet(m_pCodecCxt, &pkt);if (sd_ret != 0 && sd_ret != AVERROR(EAGAIN)) {myprint("avcodec_send_packet err, rt=%d", sd_ret);enableReConnect();}else {while (gotvframe == 0 && !m_bQuit) {gotvframe = avcodec_receive_frame(m_pCodecCxt, pAvFrame);if (gotvframe == 0){try{GetShowRectSize(&ShowRect);}catch (const std::exception&){myprint("GetClientRect throw, error");break;}m_nCurPKSize = pkt.size;   SetStreamInfoToD3d();if (pAvFrame->width != m_nActualWidth || pAvFrame->height != m_nActualHeight){myprint("video size change reconnect...");enableReConnect();m_nActualWidth = pAvFrame->width;m_nActualHeight = pAvFrame->height;av_packet_unref(&pkt);continue;}if (m_pImgConvertCtx && m_pFrameBGR && m_pOutBuffer && pAvFrame){sws_scale(m_pImgConvertCtx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0,m_pCodecCxt->height, m_pFrameBGR->data, m_pFrameBGR->linesize);{                                    try{int re = 5;for (int i = 0; m_bPlaying && re == 5 && i < 10; ++i) {     // LockRect失败时重复尝试,最多10次re = m_Dxva2D3DRender.D3DSoftDisplayFrame(m_pOutBuffer, pAvFrame->width, pAvFrame->height, ShowRect);Sleep(1);}}catch (int re){myprint("m_Dxva2D3DRender.InitD3DRender again");if (m_Dxva2D3DRender.InitD3DRender(m_showWnd, m_pCodecCxt->width, m_pCodecCxt->height) == false){myprint("m_Dxva2D3DRender.InitD3DRender again fail");av_packet_unref(&pkt);continue;}}}                                }if (m_bCapture /*&& pkt.flags == 1*/ && img_convert_ctx){sws_scale(img_convert_ctx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0, m_pCodecCxt->height,pFrameRGB->data, pFrameRGB->linesize);SaveIFrameImage(pFrameRGB->data[0], m_pCodecCxt->width, m_pCodecCxt->height);m_bCapture = false;}}}}}else if (pkt.stream_index == m_nAudioIndex){num_stream_index_err = 0;if (m_bSupportAudio) {pktdata = pkt.data;pktsize = pkt.size;if (pktsize > 0){int gotframe = 0;if (nullptr == m_pAudioCodecCxt || nullptr == pAvFrame) {myprint("m_pAudioCodecCxt == NULL || pAvFrame == NULL");break;}len = avcodec_send_packet(m_pAudioCodecCxt, &pkt);if (len != 0 && len != AVERROR(EAGAIN)){pktsize = 0;myprint("avcodec_send_packet len < 0");break;}auto data_size = av_get_bytes_per_sample(m_pAudioCodecCxt->sample_fmt); if (data_size < 0) {myprint("Failed to calculate data size\n");break;}while (gotframe == 0 && !m_bQuit) {gotframe = avcodec_receive_frame(m_pAudioCodecCxt, pAvFrame);if (!gotframe){if (bPushAudioToQueue == true && m_bEnableAudio && !m_bStopAudio){audio_frame_t audioFrame;numBytes = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);auto dstNbSamples = av_rescale_rnd(pAvFrame->nb_samples,m_src_sample_rate,pAvFrame->sample_rate,AV_ROUND_ZERO);int data_size = 0;try{auto nb = swr_convert(m_pSwrContext,(uint8_t**)outData,dstNbSamples,(const uint8_t**)pAvFrame->data,pAvFrame->nb_samples);data_size = av_samples_get_buffer_size(nullptr, m_channels_play, nb, AV_SAMPLE_FMT_S16, 1);}catch (const std::exception&){m_bSupportAudio = false;myprint("swr_convert throw err, set m_bSupportAudio false");continue;}int copy_size = 0; int copy_ptr = 0;                              for (int isub = data_size; isub > 0; isub -= copy_size) {if (isub > m_audio_buffer_notify_size) {copy_size = m_audio_buffer_notify_size;copy_ptr = data_size - isub;}elsecopy_size = isub;audioFrame.data_size = copy_size;memcpy(audioFrame.data, outData[0] + copy_ptr, copy_size);EnterCriticalSection(&m_lock);m_AudioPlayQue.push(audioFrame);LeaveCriticalSection(&m_lock);}}}}}}}else if (++num_stream_index_err > 20) {myprint("pkt.stream_index unfind, %d",pkt.stream_index);enableReConnect();}av_packet_unref(&pkt);}else {if (++num_av_read_frame_err > 10) {myprint("num_av_read_frame_err is more than 10");enableReConnect();}}}if (m_bDecodeThreadRun) {myprint("m_bDecodeThreadRun is true");enableReConnect();}if (pAvFrame)av_free(pAvFrame);if (pFrameRGB)av_free(pFrameRGB);if (pBuffer)av_free(pBuffer);if (img_convert_ctx)sws_freeContext(img_convert_ctx);if (outData[0] && outData[1]){av_free(outData[0]);av_free(outData[1]);outData[0] = 0;outData[1] = 0;}
}

四、相关下载

链接: 可执行程序下载

链接: 源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/14638.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

webpack指南

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;webpack篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南 概念 中文&#xff1a; webpack | webpack中文文档 | webpack中文网 英文&…

把越南语翻译成中文一般用什么翻译工具?《越南语翻译通》App或许能满足你的技术痛点需求!

在多语言交流日益频繁的今天&#xff0c;掌握越南语对于商务、旅游或学术交流都是一项重要技能。《越南语翻译通》App应运而生&#xff0c;旨在通过技术手段简化越南语学习和翻译过程&#xff0c;满足用户在不同场景下的需求。 核心技术 《越南语翻译通》App采用了先进的自然语…

Android Framework AMS(16)进程管理

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读AMS 进程方面的知识。关注思维导图中左上侧部分即可。 我们本章节主要是对Android进程管理相关知识有一个基本的了解。先来了解下L…

Rust Struct 属性初始化

结构体是用户定义的数据类型&#xff0c;其中包含定义特定实例的字段。结构有助于实现更容易理解的抽象概念。本文介绍几种初始化结构体对象的方法&#xff0c;包括常规方法、Default特征、第三方包实现以及构建器模式。 Struct声明与初始化 struct Employee {id: i32,name: …

Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发 1.设计公共响应数据类型 文件地址&#xff1a;utils/response404.py from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code 400def __init__(self, err_list, *args, **kwargs):data {"error_c…

数据结构:队列

目录 概念与结构底层结构的选择队列的实现队列头文件&#xff08;queue.h&#xff09;队列初始化队列的销毁入队列检查队列是否为空出队列查询队列第一个数据查询队列末尾数据查询队列有效数据个数代码试运行 概念与结构 概念&#xff1a;只允许在⼀端进行插⼊数据操作&#x…

Clickhouse集群新建用户、授权以及remote权限问题

新建用户 create user if not exists user on cluster 集群名称 IDENTIFIED WITH plaintext_password BY 密码;给用户授查询、建表、删表的权限 GRANT create table,select,drop table ON 数据库实例.* TO user on cluster 集群名称 ;再其他节点下用户建本地表成功&#…

JavaWeb--MySQL

1. MySQL概述 首先来了解一下什么是数据库。 数据库&#xff1a;英文为 DataBase&#xff0c;简称DB&#xff0c;它是存储和管理数据的仓库。 像我们日常访问的电商网站京东&#xff0c;企业内部的管理系统OA、ERP、CRM这类的系统&#xff0c;以及大家每天都会刷的头条、抖音…

i春秋-SQLi(无逗号sql注入,-- -注释)

练习平台地址 竞赛中心 题目描述 后台有获取flag的线索应该是让我们检查源码找到后台 题目内容 空白一片 F12检查源码 发现login.php 访问login.php?id1 F12没有提示尝试sql注入 常规sql注入 //联合注入得到表格列数 1 order by 3 # 1 union select 1,2,3 #&#xff08…

基于Spring Boot的电子商务平台架构

2 相关技术 2.1 SpringBoot框架介绍 Spring Boot是一种不需要代码生成的一种框架&#xff0c;并且可以不需要配置任何的XML文件就可以&#xff0c;因为Spring Boot里面自带了很多接口&#xff0c;只需要配置不同的接口就会自动的应用并且识别需要的依赖&#xff0c;在配置方面非…

华为云分布式缓存服务(DCS)专家深度解析Valkey,助力openEuler峰会

在数字化时代&#xff0c;开源技术已成为推动创新和协作的重要力量。 11月15日&#xff0c;openEuler峰会将于北京中关村国际创新中心举行。本次峰会&#xff0c;华为云分布式缓存服务&#xff08;DCS&#xff09;的两位专家将为大家深入讲解Valkey的核心特性与优势。 更多大…

如何进行产线高阶能耗数据的计算和可视化?

一、前言 在当前经济下行时期&#xff0c;越来越来多企业开始对产线进行数字化转型&#xff0c;提高企业竞争力。在产线数字化转型过程中&#xff0c;产线高阶能耗数据的计算和可视化是比较重要的一环&#xff0c;今天小编就和大家分享如何对产线能耗数据进行计算和可视化。 …

vsftp 修改端口 限制用户登录 开启防火墙 pasv模式

安装设置开机启动 yum -y install vsftpd systemctl start vsftpd systemctl enable vsftpd 修改配置&#xff0c;追加端口号到最后一行 vim /etc/vsftpd/vsftpd.conf listen_port5510 编辑 /etc/services 文件&#xff0c;将其中的三行端口改成5510 vim /etc/services ftp …

IntelliJ IDEA插件开发-代码补全插件入门开发

使用IntelliJ IDEA想必大家都有使用过代码自动补全功能&#xff0c;如输入ab&#xff0c;会自动触发补全&#xff0c;提供相应的补全建议列表。作为有追求的程序员&#xff0c;有没有想过这样的功能是如何实现的&#xff1f;本节将详细介绍如何实现一个类似的代码自动补全插件。…

❤React-React 组件基础(类组件)

❤React-React 组件基础 1、组件化开发介绍 组件化开发思想&#xff1a;分而治之 React的组件按照不同的方式可以分成类组件&#xff1a; 划分方式一&#xff08;按照组件的定义方式&#xff09; 函数组件(Functional Component )和类组件(Class Component)&#xff1b; …

Python →爬虫实践

爬取研究中心的书目 现在&#xff0c;想要把如下网站中的书目信息爬取出来。 案例一 耶鲁 Publications | Yale Law School 分析网页&#xff0c;如下图所示&#xff0c;需要爬取的页面&#xff0c;标签信息是“<p>”&#xff0c;所以用 itemssoup.find_all("p&…

机器学习: LightGBM模型(优化版)——高效且强大的树形模型

LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种基于梯度提升决策树&#xff08;GBDT&#xff09;的框架&#xff0c;由微软提出。它具有高效的训练速度、低内存占用、支持并行和GPU加速等特点&#xff0c;非常适合大规模数据的训练任务&#xff0c;尤…

《内存函数》

内存函数 1. memcpy函数 &#xff08;1&#xff09;介绍 这里通过memcpy的定义我们可以看这个函数包含三个参数&#xff0c;destination就是拷贝的目的地&#xff0c;source就是拷贝的源头&#xff0c;num就是拷贝的个数。 &#xff08;2&#xff09;使用 这里要包含头文件s…

不泄密的安全远程控制软件需要哪些技术

在数字化浪潮中&#xff0c;远程控制软件已不再是简单的辅助工具&#xff0c;而是成为企业运作和日常工作中不可或缺的一部分。随着远程办公模式的广泛采纳&#xff0c;这些软件提供了一种既安全又高效的途径来管理和访问远端系统。无论是在家办公、技术支持还是远程教育&#…

Pycharm打开终端时报错:Cannot open Local,Failed to start[powershell.exe]

问题如下&#xff1a; 解决办法&#xff1a; 修改设置中的shell path路径 英文版pycharm&#xff1a;file -> settings -> Tools -> Terminal -> Shell path 中文版pycharm&#xff1a;文件 -> 设置 -> 工具 -> 终端 -> Shell路径 将Shell路径不全 …