瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 视频硬件编解码-代码版
前言
在上一篇文章中,我们讲解了如何使用 ffmpeg-rockchip 通过命令来实现 MPP 视频硬件编解码和 RGA 硬件图形加速,在这篇文章,我将讲解如何使用 ffmpeg-rockchip 用户空间库(代码)实现 MPP 硬件编解码。
本文不仅适用于 RK3588,还适用于 RK 家族系列的芯片,具体的细节可查看官方 MPP 文档。
前置条件
本文假设你已经了解或掌握如下知识:
- ffmpeg 用户空间库使用流程
- 视频编解码原理
ffmpeg 的处理流程
上面这张图展示了 ffmpeg 的处理流程:
输入源 -> 解复用 -> 解码成帧 -> 执行各种操作,如缩放、旋转等 -> 编码 -> 复用 -> 输出
使用 ffmpeg-rochip 的好处
传统的使用硬件编解码的开发思路是:使用 ffmpeg 获取视频流,然后用 MPP 库进行硬件编解码,最后再传给 ffmpeg 进行复用,生成容器文件或推流。这样做的缺点是整个开发成本较高,需要学习 ffmpeg,还要学习 MPP库。
而现在有了 ffmpeg-rochip 之后,我们可以省略去学习使用 MPP 库的步骤,因为这个库已经帮我们封装好了 MPP 的功能,我们只需要像之前那样使用 ffmpeg 即可,只需在使用编解码器时换成 xxx_rkmpp,比如 h264_rkmpp。这样做的好处就是大大降低我们的开发学习成本。
编写思路
整个编写思路和我们日常编写 ffmpeg 时的思路是一致的,ffmpeg-rockchip 只是在 ffmpeg 的基础上封装了 MPP 和 RGA 的 api,实现了对应编解码器和过滤器,使得我们可以直接使用 ffmpeg 的 api 就能直接调用 MPP 和 RGA 功能。
下面的 demo,使用 cpp 语言,实现:”读取 MP4 文件,使用 MPP 的 h264 进行硬件解码,再使用 MPP 的 H265 进行硬件编码后输出 output.hevc 文件“的功能。
编写思路如下:
- 初始化各种上下文
- 读取当前目录下的 test.mp4 文件,进行解复用,获取视频流
- 使用 h264_rkmpp 解码器对视频帧进行硬解码
- 将解码后的视频帧使用 hevc_rkmpp 编码器进行硬编码
- 将编码的视频帧写入 output.hevc 文件中
#include <csignal>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/pixfmt.h>
}#define MP4_PATH "./test.mp4"
#define OUTPUT_FILENAME "./output.hevc"
#define DECODEC_NAME "h264_rkmpp"
#define ENCODEC_NAME "hevc_rkmpp"static const AVInputFormat *input_format;
static AVStream *video_in_stream;
static int video_in_stream_idx = -1;
static const AVCodec *rk_h264_decodec;
static const AVCodec *rk_hevc_encodec;
static AVCodecContext *rk_decodec_ctx = nullptr;
static AVCodecContext *rk_encodec_ctx = nullptr;
static AVFormatContext *mp4_fmt_ctx = nullptr;
static FILE *ouput_file;
static AVFrame *frame;
static AVPacket *mp4_video_pkt;
static AVPacket *hevc_pkt;static void encode(AVFrame *frame, AVPacket *hevc_pkt, FILE *outfile) {int ret;if (frame)printf("Send frame %3" PRId64 "\n", frame->pts);ret = avcodec_send_frame(rk_encodec_ctx, frame);if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, sizeof(errbuf));std::cerr << "Error sending a frame for encoding: " << errbuf << std::endl;exit(1);}while (ret >= 0) {ret = avcodec_receive_packet(rk_encodec_ctx, hevc_pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)return;else if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, sizeof(errbuf));std::cerr << "Error during encoding: " << errbuf << std::endl;exit(1);}printf("Write packet %3" PRId64 " (size=%5d)\n", hevc_pkt->pts,hevc_pkt->size);fwrite(hevc_pkt->data, 1, hevc_pkt->size, outfile);av_frame_unref(frame);av_packet_unref(hevc_pkt);}
}static void decode(AVPacket *mp4_video_pkt, AVFrame *frame) {int ret;ret = avcodec_send_packet(rk_decodec_ctx, mp4_video_pkt);if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, sizeof(errbuf));std::cerr << "Error sending a frame for decoding: " << errbuf << std::endl;exit(1);}while (ret >= 0) {ret = avcodec_receive_frame(rk_decodec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return;} else if (ret < 0) {char errbuf[AV_ERROR_MAX_STRING_SIZE];av_strerror(ret, errbuf, sizeof(errbuf));std::cerr << "Error during decoding: " << errbuf << std::endl;exit(1);}encode(frame, hevc_pkt, ouput_file);}
}int main(int argc, char **argv) {int ret;input_format = av_find_input_format("mp4");if (!input_format) {std::cerr << "Could not find input format" << std::endl;return EXIT_FAILURE;}// 分配一个AVFormatContext。mp4_fmt_ctx = avformat_alloc_context();if (!mp4_fmt_ctx) {std::cerr << "Could not allocate format context" << std::endl;return EXIT_FAILURE;}// 打开输入流并读取头部信息。此时编解码器尚未开启。if (avformat_open_input(&mp4_fmt_ctx, MP4_PATH, input_format, nullptr) < 0) {std::cerr << "Could not open input" << std::endl;return EXIT_FAILURE;}// 读取媒体文件的数据包以获取流信息。if (avformat_find_stream_info(mp4_fmt_ctx, nullptr) < 0) {std::cerr << "Could not find stream info" << std::endl;return EXIT_FAILURE;}// 打印视频信息av_dump_format(mp4_fmt_ctx, 0, MP4_PATH, 0);// 查找视频流if ((ret = av_find_best_stream(mp4_fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1,nullptr, 0)) < 0) {std::cerr << "Could not find video stream" << std::endl;return EXIT_FAILURE;}video_in_stream_idx = ret;video_in_stream = mp4_fmt_ctx->streams[video_in_stream_idx];std::cout << "video_in_stream->duration: " << video_in_stream->duration<< std::endl;const char *filename = OUTPUT_FILENAME;int i = 0;// 查找解码器rk_h264_decodec = avcodec_find_decoder_by_name(DECODEC_NAME);if (!rk_h264_decodec) {std::cerr << "Codec '" << DECODEC_NAME << "' not found" << std::endl;exit(1);}rk_decodec_ctx = avcodec_alloc_context3(rk_h264_decodec);if (!rk_decodec_ctx) {std::cerr << "Could not allocate video rk_h264_decodec context"<< std::endl;exit(1);}// 将视频参数复制到rk_h264_decodec上下文中。if (avcodec_parameters_to_context(rk_decodec_ctx, video_in_stream->codecpar) <0) {std::cerr << "Could not copy video parameters to rk_h264_decodec context"<< std::endl;exit(1);}AVDictionary *opts = NULL;av_dict_set_int(&opts, "buf_mode", 1, 0);if (avcodec_open2(rk_decodec_ctx, rk_h264_decodec, &opts) < 0) {std::cerr << "Could not open rk_h264_decodec" << std::endl;exit(1);}// 查找编码器rk_hevc_encodec = avcodec_find_encoder_by_name(ENCODEC_NAME);if (!rk_hevc_encodec) {std::cerr << "Codec '" << ENCODEC_NAME << "' not found" << std::endl;exit(1);}rk_encodec_ctx = avcodec_alloc_context3(rk_hevc_encodec);if (!rk_encodec_ctx) {std::cerr << "Could not allocate video rk_hevc_encodec context"<< std::endl;exit(1);}// 设置编码器参数rk_encodec_ctx->width = video_in_stream->codecpar->width;rk_encodec_ctx->height = video_in_stream->codecpar->height;rk_encodec_ctx->pix_fmt = AV_PIX_FMT_NV12;rk_encodec_ctx->time_base = video_in_stream->time_base;rk_encodec_ctx->framerate = video_in_stream->r_frame_rate;rk_encodec_ctx->gop_size = 50;rk_encodec_ctx->bit_rate = 1024 * 1024 * 10;av_opt_set(rk_encodec_ctx->priv_data, "profile", "main", 0);av_opt_set(rk_encodec_ctx->priv_data, "qp_init", "23", 0);av_opt_set_int(rk_encodec_ctx->priv_data, "rc_mode", 0, 0);ret = avcodec_open2(rk_encodec_ctx, rk_hevc_encodec, nullptr);if (ret < 0) {std::cerr << "Could not open rk_hevc_encodec: " << std::endl;exit(1);}mp4_video_pkt = av_packet_alloc();if (!mp4_video_pkt)exit(1);hevc_pkt = av_packet_alloc();if (!hevc_pkt)exit(1);ouput_file = fopen(filename, "wb");if (!ouput_file) {std::cerr << "Could not open " << filename << std::endl;exit(1);}frame = av_frame_alloc();if (!frame) {std::cerr << "Could not allocate video frame" << std::endl;exit(1);}while (true) {ret = av_read_frame(mp4_fmt_ctx, mp4_video_pkt);if (ret < 0) {std::cerr << "Could not read frame" << std::endl;break;}if (mp4_video_pkt->stream_index == video_in_stream_idx) {std::cout << "mp4_video_pkt->pts: " << mp4_video_pkt->pts << std::endl;decode(mp4_video_pkt, frame);}av_packet_unref(mp4_video_pkt);i++;}// 确保将所有帧写入av_packet_unref(mp4_video_pkt);decode(mp4_video_pkt, frame);encode(nullptr, mp4_video_pkt, ouput_file);fclose(ouput_file);avcodec_free_context(&rk_encodec_ctx);avformat_close_input(&mp4_fmt_ctx);avformat_free_context(mp4_fmt_ctx);av_frame_free(&frame);av_packet_free(&mp4_video_pkt);av_packet_free(&hevc_pkt);return 0;
}
将上面的代码放入 main.cpp 中,将 test.mp4 文件放入当前目录,在开发板中运行如下命令编译并运行:
g++ -o main main.cpp -lavformat -lavcodec -lavutil./main
确保你的 rk 开发板环境中有 ffmpeg-rockchip 库,如果没有的可以参考我上篇文章的编译教程:《瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 硬件编解码和 RGA 图形加速-命令版》
查看 VPU 的运行情况,如下说明成功使用了硬件编解码功能。如果不知道怎么查看 VPU 的运行情况,可以参考我这篇文章:《瑞芯微 RK 系列 RK3588 CPU、GPU、NPU、VPU、RGA、DDR 状态查看与操作》。
优化点
以上的代码示例有个缺点,就是解码时会将视频帧上传到 VPU,之后传回内存,编码时又上传到 VPU,编码后再传回内存。这样就造成了不必要的数据拷贝,我们可以将视频帧解码之后,在 VPU 编码后再传回内存,提高编解码效率。
实现方案是使用 hw_device_ctx
上下文,由于篇幅问题,这里不给出代码示例。有需要的小伙伴可以在评论区回复或直接私聊我。
结语
本篇文章介绍了如何使用 ffmpeg-rockchip 进行 MPP 硬件编解码,在下一篇文章,我将介绍如何使用 ffmpeg-rockchip 使用 RGA 2D 图形加速,RGA 可以实现图像缩放、旋转、bitBlt、alpha混合等常见的2D图形操作。
如果觉得本文写得不错,请麻烦帮忙点赞、收藏、转发,你的支持是我继续写作的动力。我是 Leon_Chenl,我们下篇文章见~
相关文章:
瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 视频硬件编解码-代码版
前言 在上一篇文章中,我们讲解了如何使用 ffmpeg-rockchip 通过命令来实现 MPP 视频硬件编解码和 RGA 硬件图形加速,在这篇文章,我将讲解如何使用 ffmpeg-rockchip 用户空间库(代码)实现 MPP 硬件编解码。 本文不仅适…...
MySQL数据库(SQL分类)
SQL分类 分类全称解释DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)DMLData Manipulation Language数据操作语言,用来对数据库表中的数据进行增删改DQLData Query Languag…...
SpringBoot-Day1
1.Springboot入门 创建Maven工程 导入spring-boot-stater-web起步依赖 编写Controller 提供启动类 2.yml配置信息书写与获取 书写 # 发件人信息 email:user: 172349823457qq.comcode: sajdajlwhjfgfkllwhost: smtp.qq.comauth: true # 学生爱好 hobbies:- 打篮球- 踢…...
【JavaScript】基础内容,HTML如何引用JavaScript, JS 常用的数据类型
HTML 嵌入 Javascript 的方式 引入外部 js 文件 <head> <script Language "javaScript" src"index.js"/> </head>内部声明 <head> <script language"javascript">function hello(){alert("hello word&qu…...
mysql中创建计算字段
目录 1、计算字段 2、拼接字段 3、去除空格和使用别名 (1)去除空格 (2)使用别名:AS 4、执行算术计算 5、小结 博主用的是mysql8 DBMS,附上示例资料: 百度网盘链接: https://pan.baidu.co…...
如何优化zibll子比主题SEO并设置有效robots文件
如果你不知道 robots.txt 是什么,也不确定如何正确地设置它,本篇文章会向您介绍适用于子比主题的 robots.txt 文件,利用它可以提升 SEO 的效果,避免收录无关页面,从而解决网站被收录但无权重的困境。 作为一款高效的 …...
线程间通信
线程间通信(Inter-Thread Communication, 简称ITC)是指在多线程编程中,不同线程之间如何交换信息或协调彼此的行为。良好的线程间通信机制是构建高效、可靠的并发程序的关键。Java语言提供了多种内置工具和库来支持线程间的通信,包…...
【实践】操作系统智能助手OS Copilot新功能测评
一、引言 数字化加速发展,尤其人工智能的发展速度越来越快。操作系统智能助手成为提升用户体验与操作效率的关键因素。OS Copilot借助语言模型,人工智能等,对操作系统的自然语言交互操作 推出很多功能,值得开发,尤其运…...
今年的电商年货节,主流的营销策略是怎样?
随着一年的年关将近,新一年的CNY营销也逐渐拉开帷幕。考虑到此时消费需求的膨胀,这个时间不论对于线上还是线下市场而言,都是重要的营销节点。今年CNY营销,电商平台上的主流营销策略是这样?就让我们来简单了解下概况。…...
Java设计模式——单例模式(特性、各种实现、懒汉式、饿汉式、内部类实现、枚举方式、双重校验+锁)
文章目录 单例模式1️⃣特性💪单例模式的类型与实现:类型懒汉式实现(线程不安全)懒汉式实现(线程安全)双重锁校验懒汉式(线程安全)饿汉式实现(线程安全)使用类的内部类实现⭐枚举方式实现单例(推荐)👍 单例…...
基于 Python 的学生成绩管理系统设计与实现
标题:基于 Python 的学生成绩管理系统设计与实现 内容:1.摘要 摘要:本文介绍了一个基于 Python 的学生成绩管理系统的设计与实现。该系统旨在提高学生成绩管理的效率和准确性,方便教师和学生进行成绩查询和分析。本文详细描述了系统的设计思路、功能模块…...
局域网共享文件夹实现两台Windows电脑之间传输文件
文章目录 1. 启用网络发现和文件共享2. 设置共享文件夹3. 记录主电脑的IP地址4. 在第二台电脑访问共享文件夹5. 故障排查6. 启用文件共享未生效方案1:检查服务状态方案2:检查防火墙设置方案3:检查网络类型方案4:使用“管理员命令提…...
JS的事件循环机制
<script>setTimeout(()>{console.log(1)},1000)setTimeout(()>{console.log(2)},3000)var start Date.now();while ( (Date.now() - start) < 10000 ){}console.log(3)</script>执行如下代码会发现先打印3,再打印1 再打印2。 现象本质还是因为…...
《自动驾驶与机器人中的SLAM技术》ch9:自动驾驶车辆的离线地图构建
目录 1 点云建图的流程 2 前端实现 2.1 前端流程 2.2 前端结果 3 后端位姿图优化与异常值剔除 3.1 两阶段优化流程 3.2 优化结果 ① 第一阶段优化结果 ② 第二阶段优化结果 4 回环检测 4.1 回环检测流程 ① 遍历第一阶段优化轨迹中的关键帧。 ② 并发计算候选回环对…...
环境搭建——Mysql、Redis、Rocket MQ部署
前言 在搭建分布式系统时,MySQL、Redis 和 RocketMQ 是常用的基础服务。每个服务各自的功能不同,但它们在数据存储、缓存、消息队列等方面不可或缺。如果你是初学者,别担心,本文会一步步详细教你如何在服务器上通过 Docker 部署这…...
Pycharm连接远程解释器
这里写目录标题 0 前言1 给项目添加解释器2 通过SSH连接3 找到远程服务器的torch环境所对应的python路径,并设置同步映射(1)配置服务器的系统环境(2)配置服务器的conda环境 4 进入到程序入口(main.py&#…...
git的基本操作
创建分支: 1,拉去develop代码; 2,git checkout develop切换到develop; 3,git branch lyb/lyb_develop ; 4,git push --set-upstream origin lyb/lyb_develop 切换分支,上…...
Linux软件包管理工具概览
目录 RPM(RedHat Package Manager) DPKG(Debian Packager) APT(Advanced Package Tool) YUM(Yellowdog Updater, Modified) DNF(Dandified YUM) 总结 在…...
unity学习16:unity里向量的计算,一些方法等
目录 1 unity里的向量: 2 向量加法 2.1 向量加法的几何意义 2.2向量加法的标量算法 3 向量减法 3.1 向量减法的几何意义 3.2 向量减法的标量算法 4 向量的标量乘法 5 向量之间的乘法要注意是左乘 还是右乘 5.1 注意区别 5.2 向量,矩阵&#x…...
HTML拖拽功能(纯html5+JS实现)
1、HTML拖拽--单元行拖动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><…...
w158医院资源管理系统的设计与实现
🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...
【计算机网络】lab3 802.11 (无线网络帧)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀计算机网络_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...
linux进程
课本概念:程序的⼀个执行实例,正在执行的程序等内核观点:担当分配系统资源(CPU时间,内存)的实体。 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合.课本上称之为PCB&…...
pytest-allure框架简单封装----测试报告
安装allure-commandline---可以支持allure命令 把对应的压缩包解压后,把xxx/bin配置到环境变量的path去 可以输入allure -version检查版本 pip install allure-pytest2.11.1 生成测试报告 import pytest pytest_args ["-s","-v","--capturesys…...
【2025最新计算机毕业设计】基于SpringBoot+Vue奶茶点单系统(高质量源码,提供文档,免费部署到本地)
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...
HTML中最基本的东西
本文内容的标签,将是看懂HTML的最基本之基本 ,是跟您在写文章时候一样内容。一般想掌握极其容易,但是也要懂得如何使用,过目不忘,为手熟尔。才是我们学习的最终目的。其实边看边敲都行,或者是边看边复制粘贴…...
Open FPV VTX开源之ardupilot配置
Open FPV VTX开源之ardupilot配置 1. 源由2. 配置3. 总结4. 参考资料5. 补充5.1 飞控固件版本5.2 配置Ardupilot的BF OSD5.3 OSD偏左问题 1. 源由 飞控嵌入式OSD - ardupilot配置使用ardupliot配套OSD图片。 Choose correct font depending on Flight Controller SW. ──>…...
基于OQuPy的量子编程实例探究:理论、实践与展望
基于OQuPy的量子编程探究:理论、分析与实践 一、引言 1.1 研究背景与意义 近年来,量子计算作为一种革命性的计算范式,在科学界与产业界引发了广泛关注。它依托量子力学原理,运用量子比特(qubit)进行信息处理,与传统计算相比,具备并行处理、指数级加速等显著优势,为解…...
深入理解 ECMAScript 2024 新特性:正则表达式 /v 标志
ECMAScript 2024 (ES15)标准引入了新的正则表达式标志 /v,这一新增功能不仅优化了多行匹配的处理,还增加了对特殊字符匹配的支持。这一变革对于需要处理复杂文本数据的应用场景尤为重要,比如日志分析、代码审核等。接下…...
iOS 逆向学习 - Inter-Process Communication:进程间通信
iOS 逆向学习 - Inter-Process Communication:进程间通信 一、进程间通信概要二、iOS 进程间通信机制详解1. URL Schemes2. Pasteboard3. App Groups 和 Shared Containers4. XPC Services 三、不同进程间通信机制的差异四、总结 一、进程间通信概要 进程间通信&am…...
Prompt工程框架介绍与场景选择
文章目录 Prompt工程框架介绍1. CREATE框架2. RACE框架3. RISE框架4. ROSES框架5. E.R.A框架6. SAGE框架7. CARE框架8. PEAR框架9. TIER框架10. LEAP框架11. DEEP框架12. WISE框架13. FOCUS框架14. CLEAR框架15. SMART框架16. CLEAR框架17. LEAN框架18. BRIEF框架19. FAST框架2…...
信号量机制之苹果-橘子问题
桌上有一空盘,允许存放一种水果。爸爸可向盘中放苹果,也可向盘中放橘子,儿子专等吃盘中的橘子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一个水果供吃者取用。 要求:请用信号量机制实现爸爸、儿子、女儿三个并发…...
工业路由器和工业交换机,如何打造高效稳定的工业网络?
工业路由器和工业交换机各有千秋,但如何将它们完美结合,构建稳定高效的工业网络?答案就在这里! 工业物联网(IIoT)是高效、稳定的工业网络成为智慧工厂、工业自动化和远程监控等场景的基础支撑。工业路由器…...
【IDEA 2024】学习笔记--文件选项卡
在我们项目的开发过程中,由于项目涉及的类过多,以至于我们会打开很多的窗口。使用IDEA默认的配置,个人觉得十分不便。 目录 一、设置多个文件选项卡按照文件字母顺序排列 二、设置多个文件选项卡分行显示 一、设置多个文件选项卡按照文件字…...
LabVIEW光流算法的应用
该VI展示了如何使用NI Vision Development Module中的光流算法来计算图像序列中像素的运动矢量。通过该方法,可以实现目标跟踪、运动检测等功能,适用于视频处理、机器人视觉和监控领域。程序采用模块化设计,包含图像输入、算法处理、结果展示…...
WPF 如何添加系统托盘
1.使用Nuget 添加 handycontrol cs xmlns:hc"https://handyorg.github.io/handycontrol" 2.窗体添加控件cs <hc:NotifyIcon x:Name"NotifyIconContextContent" Text"软件名称" ContextMenu"{StaticResource ContextMenu}" Click&…...
小游戏前端地区获取
目前前端获取除了太平洋,没有其它的了。 //在JS中都是使用的UTF-8,然而requst请求后显示GBK却是乱码,对传入的GBK字符串,要用数据流接收,responseType: "arraybuffer" tt.request({url: "https://whoi…...
美摄科技为企业打造专属PC端视频编辑私有化部署方案
美摄科技,作为视频编辑技术的先行者,凭借其在多媒体处理领域的深厚积累,为企业量身打造了PC端视频编辑私有化部署解决方案,旨在帮助企业构建高效、安全、定制化的视频创作平台,赋能企业内容创新,提升品牌影…...
【0x005B】HCI_Write_Default_Erroneous_Data_Reporting命令详解
目录 一、命令概述 二、命令格式及参数 2.1. HCI_Write_Default_Erroneous_Data_Reporting命令格式 2.2. Erroneous_Data_Reporting 三、生成事件及参数 3.1. HCI_Command_Complete事件 3.2. 状态码(Status) 四、命令执行流程 4.1. 命令发起阶段(主机端) 4.2. 命…...
1月13日学习
[HITCON 2017]SSRFme 直接给了源代码,题目名称还是ssrf,那么该题大概率就是SSRF的漏洞,进行代码审计。 <?php// 检查是否存在 HTTP_X_FORWARDED_FOR 头,如果存在,则将其拆分为数组,并将第一个 IP 地址…...
数据平台浅理解
定义 数据平台架构是指用于收集、存储、处理和分析数据的一系列组件、技术和流程的整体架构设计。它就像是一个复杂的数据生态系统的蓝图,旨在高效地管理数据从产生源头到产生价值的整个生命周期。 主要层次 数据源层 这是数据的起点,包含各种类型的数据…...
高通,联发科(MTK)等手机平台调优汇总
一、常见手机型号介绍: ISP除了用在安防行业,还有手机市场,以及目前新型的A/VR眼睛,机器3D视觉机器人,医疗内窥镜这些行业。 下面是一些最近几年发布的,,,旗舰SOC型号: 1.联发科:天玑92…...
win10 Outlook(new) 企业邮箱登录 登录失败。请在几分钟后重试。
windows系统经常弹出使用Outlook(new),自动切过去。 但是登录企业的内网邮箱,折腾了好几次都使用不了。排查网络等问题,在社区找到了答案。 推出一年多不支持企业账户,所以之前的折腾都是浪费时间。 因为这个答案不太…...
Sentaurus TCAD学习笔记:transform指令
目录 一、transform指令简介二、transform指令的实现1.cut指令2.flip指令3.rotate指令4.stretch指令5.translate指令6.reflect指令 三、transform指令示例 一、transform指令简介 在Sentaurus中,如果需要对器件进行翻转、平移等操作,可以通过transform指…...
SpringBoot+Lombok项目实体属性名xXxx格式,前端接收不到
问题解析 今天发现后端传给前端的实体类中,有属性为xXxxx格式的,前端也使用相同名称接收,结果却不显示值!研究了一会发现接口请求回来后,原xXxxx的属性名,会被转为全小写。具体原因为:使用Lombo…...
初识JAVA-面向对象的三大特征之多态
1. 重温面向对象 面向对象是一种解决问题的思想,它把计算机程序看作是各种对象组合起来的。每个对象都有自己的数据(属性)和行为(方法),主要依靠对象之间的交互来解决和实现问题。Java是一门纯面向对象的语…...
测试链接 勿看
这里写自标题 自定义定阿萨德义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定…...
SQL中的行转列,列转行
SQL中的行列转换 1. 导入 有这样两张表,这两张表如何互相转换 student_table score_table 2. 行转列 使用 UNION ALL -- 行转列 SELECT name,语文 as subject,chinese_score as score FROM student_table UNION ALL SELECT name,数学 as subject,math_score…...
Windows的Redis查看自己设置的密码并更改设置密码
查看密码 由于我的Redis安装很久了,所以忘记是否有设置密码,查看步骤如下: 启动redis,启动流程可以看这篇文章:https://blog.csdn.net/changyana/article/details/127679871 在redis安装目录下打开redis-cli.exe&…...
初阶数据结构【队列及其接口的实现】
目录 前言一、队列的概念及结构二、队列的实现方式三、队列的实现3.1 基本结构3.2 队列基本功能接口初始化队列销毁队列 3.3 入队列接口3.4 出队列接口3.5 队列的其它接口获取队列头部元素获取队列队尾元素检测队列是否为空获取队列中有效元素个数 3.6 测试 总结 前言 上一期我…...