当前位置: 首页 > news >正文

Android MediaCodec将h264实时视频流数据解码为yuv,并转换yuv的颜色格式为nv21

初始化mediacodec

    private MediaCodec mediaCodec;private ByteBuffer[] inputBuffers;private void initMediaCodec(Surface surface) {try {Log.d(TAG, "onGetNetVideoData: ");//创建解码器 H264的Type为  AACmediaCodec = MediaCodec.createDecoderByType("video/avc");//创建配置MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", Width, Height);//设置解码预期的帧速率【以帧/秒为单位的视频格式的帧速率的键】mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 20);mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUV420Flexible);//
//            byte[] headerSps = {0, 0, 0, 1, 103, 66, 0, 41, -115, -115, 64, 80, 30, -48, 15, 8, -124, 83, -128};
//            byte[] headerPps = {0, 0, 0, 1, 104, -54, 67, -56};
//
//            mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(headerSps));
//            mediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(headerPps));//配置绑定mediaFormat和surfacemediaCodec.configure(mediaFormat, null, null, 0);mediaCodec.start();} catch (IOException e) {e.printStackTrace();//创建解码失败Log.e(TAG, "创建解码失败");}inputBuffers = mediaCodec.getInputBuffers();}

处理数据,解码h264数据为yuv格式

这里传入的是h264格式的实时视频流数据。

    private void onFrame(byte[] buf, int offset, int length) {MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();//查询10000毫秒后,如果dSP芯片的buffer全部被占用,返回-1;存在则大于0int inIndex = mediaCodec.dequeueInputBuffer(10000);if (inIndex >= 0) {//根据返回的index拿到可以用的bufferByteBuffer byteBuffer = inputBuffers[inIndex];//清空缓存byteBuffer.clear();//开始为buffer填充数据byteBuffer.put(buf);//填充数据后通知mediacodec查询inIndex索引的这个buffer,mediaCodec.queueInputBuffer(inIndex, 0, length, mCount * 20, 0);mCount++;} else {Log.i(TAG, "inIndex < 0");//等待查询空的bufferreturn;}//mediaCodec 查询 "mediaCodec的输出方队列"得到索引int outIndex = mediaCodec.dequeueOutputBuffer(info, 10000);Log.e(TAG, "解码输出outIndex " + outIndex);if (outIndex >= 0) {//dsp的byteBuffer无法直接使用ByteBuffer byteBuffer = mediaCodec.getOutputBuffer(outIndex);//设置偏移量byteBuffer.position(info.offset);byteBuffer.limit(info.size + info.offset);byte[] ba = new byte[byteBuffer.remaining()];byteBuffer.get(ba);//需要预先分配与NV12相同大小的字节数组byte[] yuv = new byte[ba.length];//不确定是什么颜色格式,挨个试的//convertI420ToNV21(ba, yuv, Width, Height);//convertYV12toNV21(ba, yuv, Width, Height);convertNV12toNV21(ba, yuv, Width, Height);NV21Data(yuv);//检查所支持的颜色格式
//            MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType("video/avc");
//             for (int i = 0; i < capabilities.colorFormats.length; i++) {
//                int format = capabilities.colorFormats[i];
//
//                //华为平板:COLOR_FormatYUV420SemiPlanar、COLOR_FormatYUV420Planar
//                //魅族手机:COLOR_FormatYUV420SemiPlanar
//                //rk3588s: COLOR_FormatYUV420Planar、COLOR_FormatYUV420Flexible、COLOR_FormatYUV420PackedSemiPlanar、COLOR_FormatYUV420SemiPlanar
//                switch (format) {
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar://(对应 I420 or YV12)
//                        Log.i("COLOR_Format_TAG", "=========COLOR_FormatYUV420Planar");
//                        byte[] convertNv21YUV420Planar = new byte[ba.length];
//                        //不确定是什么颜色格式,挨个试的convertI420ToNV21(ba, convertNv21YUV420Planar, Width, Height);convertYV12toNV21(ba, convertNv21YUV420Planar, Width, Height);
//                        long l1 = System.currentTimeMillis();
//                        convertNV12toNV21(ba, convertNv21YUV420Planar, Width, Height);
//                        Log.i("耗时测试", "转为nv21的耗时: " + (System.currentTimeMillis() - l1));
//                        long l2 = System.currentTimeMillis();
//                        NV21Data(convertNv21YUV420Planar);
//                        Log.i("耗时测试", "识别耗时: " + (System.currentTimeMillis() - l2));
//                        continue;
//
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar://NV12
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420SemiPlanar");
//                        byte[] nv21YUV420SemiPlanar = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420SemiPlanar, Width, Height);
//                        NV21Data(nv21YUV420SemiPlanar);
//
//                        continue;
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420PackedSemiPlanar");
//                        byte[] nv21YUV420PackedSemiPlanar = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420PackedSemiPlanar, Width, Height);
//                        NV21Data(nv21YUV420PackedSemiPlanar);
//                        continue;
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible:
//                        byte[] nv21YUV420YUV420Flexible = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420YUV420Flexible, Width, Height);
//                        NV21Data(nv21YUV420YUV420Flexible);
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420Flexible");
//                        continue;
//                    default:
//                        continue;
//
//                }
//
//            }//如果surface绑定了,则直接输入到surface渲染并释放mediaCodec.releaseOutputBuffer(outIndex, false);} else {Log.e(TAG, "没有解码成功");}}

处理获取到的nv21颜色格式的yuv数据

    private int printImageStatus = 0;private void NV21Data(byte[] nv21) {//将nv21视频流数据传入YuvImage中,转换成bitmap之后,显示在imageview上、//或者保存为png图片到本地,如果不出现灰色、不出现蓝色图像和红色图像颜色颠倒,//图像显示正常,则说明是标准的nv21格式视频流数据YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, Width, Height, null);ByteArrayOutputStream baos = new ByteArrayOutputStream();yuvImage.compressToJpeg(new Rect(0, 0, Width, Height), 100, baos);byte[] data = baos.toByteArray();Log.i(TAG, "NV21Data-data: " + data.length);Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);if (bitmap != null) {runOnUiThread(new Runnable() {@Overridepublic void run() {mIvShowImage.setImageBitmap(bitmap);}});//保存bitmap为png图片if (printImageStatus == 0) {printImageStatus = 1;try {File myCaptureFile = new File(Environment.getExternalStorageDirectory(), "img.png");BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);bos.flush();bos.close();} catch (Exception e) {e.printStackTrace();}}}}

 yuv视频数据颜色格式转换

    public static void convertI420ToNV21(byte[] i420, byte[] nv21, int width, int height) {System.arraycopy(i420, 0, nv21, 0, width * height);int offset = width * height;for (int i = 0; i < width * height / 4; i++) {nv21[offset + 2 * i] = i420[offset + i + width * height / 4];nv21[offset + 2 * i + 1] = i420[offset + i];}}public static void convertYV12toNV21(byte[] yv12, byte[] nv21, int width, int height) {int size = width * height;int vOffset = size;int uOffset = size + (size / 4);// Copy Y channel as it isSystem.arraycopy(yv12, 0, nv21, 0, size);for (int i = 0; i < size / 4; i++) {nv21[vOffset + (i * 2)] = yv12[vOffset + i];      // Vnv21[vOffset + (i * 2) + 1] = yv12[uOffset + i];  // U}}public static void convertNV12toNV21(byte[] nv12, byte[] nv21, int width, int height) {int size = width * height;int offset = size;// copy Y channel as it isSystem.arraycopy(nv12, 0, nv21, 0, offset);for (int i = 0; i < size / 4; i++) {nv21[offset + (i * 2) + 1] = nv12[offset + (i * 2)];       // Unv21[offset + (i * 2)] = nv12[offset + (i * 2) + 1];       // V}}

h264实时视频流的数据来源

    @Overridepublic void onPacketEvent(byte[] data) {onFrame(data, 0, data.length);//写入h264视频流到sdcard中//wirte2file(data, data.length);}

写入h264视频流到sdcard中

private String dsetfilePath = Environment.getExternalStorageDirectory() + "/" + "test.h264";private void wirte2file(byte[] buf, int length) {if (isStart) {if (BufOs == null) {destfile = new File(dsetfilePath);try {destfs = new FileOutputStream(destfile);BufOs = new BufferedOutputStream(destfs);Log.d(TAG, "wirte2file-new ");} catch (FileNotFoundException e) {// TODO: handle exceptionLog.i("TRACK", "initerro" + e.getMessage());Log.d(TAG, "wirte2file-FileNotFoundException:" + e.getMessage());e.printStackTrace();}}try {BufOs.write(buf, 0, length);BufOs.flush();Log.d(TAG, "wirte2file-write");} catch (Exception e) {Log.d(TAG, "wirte2file-e: " + e.getMessage());// TODO: handle exception}}}private boolean isStart;public void onStop(View view) {isStart = false;Toast.makeText(this, "停止保存", Toast.LENGTH_SHORT).show();}public void onStart(View view) {isStart = true;Toast.makeText(this, "开始保存", Toast.LENGTH_SHORT).show();}

rtsp获取h264实时视频流数据

public class FFDemuxJava {static {System.loadLibrary("demux");}private long m_handle = 0;private EventCallback mEventCallback = null;public void init(String url) {m_handle = native_Init(url);}public void Start() {native_Start(m_handle);}public void stop() {native_Stop(m_handle);}public void unInit() {native_UnInit(m_handle);}public void addEventCallback(EventCallback callback) {mEventCallback = callback;}private void playerEventCallback(int msgType, float msgValue) {if(mEventCallback != null)mEventCallback.onMessageEvent(msgType, msgValue);}private void packetEventCallback(byte[]data) {if(mEventCallback != null)mEventCallback.onPacketEvent(data);}private native long native_Init(String url);private native void native_Start(long playerHandle);private native void native_Stop(long playerHandle);private native void native_UnInit(long playerHandle);public interface EventCallback {void onMessageEvent(int msgType, float msgValue);void onPacketEvent(byte []data);}}
 编写C代码加载ffmpeg库
#include <jni.h>
#include <string>#include "FFBridge.h"extern "C"
{
#include <libavutil/time.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/packet.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/opt.h>
};extern "C" JNIEXPORT jstring JNICALL
Java_com_qmcy_demux_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}extern "C" JNIEXPORT jstring JNICALL
Java_com_qmcy_demux_MainActivity_GetVersion(JNIEnv* env,jobject /* this */) {char strBuffer[1024 * 4] = {0};strcat(strBuffer, "libavcodec : ");strcat(strBuffer, AV_STRINGIFY(LIBAVCODEC_VERSION));strcat(strBuffer, "\nlibavformat : ");strcat(strBuffer, AV_STRINGIFY(LIBAVFORMAT_VERSION));strcat(strBuffer, "\nlibavutil : ");strcat(strBuffer, AV_STRINGIFY(LIBAVUTIL_VERSION));strcat(strBuffer, "\nlibavfilter : ");strcat(strBuffer, AV_STRINGIFY(LIBAVFILTER_VERSION));strcat(strBuffer, "\nlibswresample : ");strcat(strBuffer, AV_STRINGIFY(LIBSWRESAMPLE_VERSION));strcat(strBuffer, "\nlibswscale : ");strcat(strBuffer, AV_STRINGIFY(LIBSWSCALE_VERSION));strcat(strBuffer, "\navcodec_configure : \n");strcat(strBuffer, avcodec_configuration());strcat(strBuffer, "\navcodec_license : ");strcat(strBuffer, avcodec_license());//LOGCATE("GetFFmpegVersion\n%s", strBuffer);return env->NewStringUTF(strBuffer);
}extern "C" JNIEXPORT jlong JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Init(JNIEnv *env, jobject obj, jstring jurl)
{const char* url = env->GetStringUTFChars(jurl, nullptr);FFBridge *bridge = new FFBridge();bridge->Init(env, obj, const_cast<char *>(url));env->ReleaseStringUTFChars(jurl, url);return reinterpret_cast<jlong>(bridge);
}extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Start(JNIEnv *env, jobject obj, jlong handle)
{if(handle != 0){FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);bridge->Start();}}extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Stop(JNIEnv *env, jobject obj, jlong handle)
{if(handle != 0){FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);bridge->Stop();}
}extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1UnInit(JNIEnv *env, jobject obj, jlong handle)
{if(handle != 0){FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);bridge->UnInit();delete bridge;}
}

源码地址icon-default.png?t=N7T8https://gitee.com/baipenggui/demux_demo.git

相关文章:

Android MediaCodec将h264实时视频流数据解码为yuv,并转换yuv的颜色格式为nv21

初始化mediacodec private MediaCodec mediaCodec;private ByteBuffer[] inputBuffers;private void initMediaCodec(Surface surface) {try {Log.d(TAG, "onGetNetVideoData: ");//创建解码器 H264的Type为 AACmediaCodec MediaCodec.createDecoderByType("v…...

Postgresql SQL 字段拼接

本文介绍Postgresql 数据库sql字段拼接的方法。 1.使用字符串连接函数 select pkey || - || vname as "项目-版本" from test_jira_project_verison; 2.使用字符串连接操作符 select CONCAT(pkey, -, vname) as "项目-版本" from test_jira_project_ve…...

MySQL 迁移完不能快速导数据了?

关于 5.6 升级到 5.7 之后&#xff0c;GTID 的相关功能的注意事项。 作者&#xff1a;秦福朗&#xff0c;爱可生 DBA 团是队成员&#xff0c;负责项目日常问题处理及公司平台问题排查。热爱互联网&#xff0c;会摄影、懂厨艺&#xff0c;不会厨艺的 DBA 不是好司机&#xff0c;…...

Lazysysadmin靶机

信息收集 主机发现 nmap -sn 192.168.88.0/24 //-sn&#xff1a;制作主机发现&#xff0c;不做端口扫描&#xff1b;扫描结果包含本机IP 端口扫描 nmap --min-rate 10000 -p- 192.168.88.136 扫描端口详细信息 端口扫描发现&#xff0c;该主机的22、80、139、445、3306、…...

LeetCode09——回文数

LeetCode09 自己写的解,转化为字符串再反转&#xff0c;比较笨。 import java.util.Scanner; public class Result01 {public static void main(String[] args) {System.out.println("请输入整数&#xff0c;我来帮您判断是否是回文数。");Scanner scanner new Sc…...

云安全—分布式基础

0x00 前言 云必然是依赖于分布式技术来进行实现的&#xff0c;所以有必要学习和来了解分布式相关的内容 0x01 分布式计算 1.基本概述 分布式计算的定义&#xff1a;通过网络互联的计算机都具有一定的计算能力&#xff0c;他们之间互相传递数据&#xff0c;实现信息共享&…...

Spring(18) @Order注解介绍、使用、底层原理

目录 一、简介二、List 注入使用示例2.1 测试接口类2.2 测试接口实现类12.3 测试接口实现类22.4 启动类&#xff08;测试&#xff09;2.5 测试结果场景一&#xff1a;场景二&#xff1a; 三、CommandLineRunner 使用示例3.1 接口实现类13.2 接口实现类23.3 测试结果场景一&…...

目标检测YOLO实战应用案例100讲-基于改进YOLOv6的轧钢表面细小缺陷检测

目录 前言 存在的问题 轧钢缺陷图像特征分析 2.1单一类型缺陷 2.2面状缺陷...

leetcode:507. 完美数(python3解法)

难度&#xff1a;简单 对于一个 正整数&#xff0c;如果它和除了它自身以外的所有 正因子 之和相等&#xff0c;我们称它为 「完美数」。 给定一个 整数 n&#xff0c; 如果是完美数&#xff0c;返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;num…...

智能物联网解决方案:蓝牙IOT主控模块打造高效监测和超低功耗

物联网蓝牙模块&#xff0c;无论单模&#xff0c;还是双模&#xff0c;或者双模音频的选择&#xff0c;如下文说描述&#xff1a; 蓝牙芯片模块市场的百花齐放&#xff0c;也带来的工程师在选型时碰到很大的困难&#xff0c;但是无论是做半成品&#xff0c;还是做成品&#xf…...

vue 拿到数据后,没有重新渲染视图,nuxt.js拿到数据后,没有重新渲染视图,强制更新视图

以下为Vue2的解决方案 一、 Vue.set&#xff08;&#xff09; 问&#xff1a;什么情况下使用&#xff1f; 答&#xff1a;如果你向响应式数据添加新的“属性”&#xff0c;理论上&#xff0c;一般情况下是没问题的&#xff0c;但是&#xff0c;如果你的级别比较深&#xff0c;又…...

Docker基础操作命令演示

Docker中的常见命令&#xff0c;可以参考官方文档&#xff1a;https://docs.docker.com/engine/reference/commandline/cli/ 1、常见命令介绍 其中&#xff0c;比较常见的命令有&#xff1a; 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerReg…...

XTU-OJ 1175-Change

题目描述 一个班有N个学生&#xff0c;每个学生有第一学期成绩Xi,第二学期成绩Yi&#xff0c;请问成绩上升&#xff0c;持平&#xff0c;下降的人数。 输入 每个样例的第一行是整数N(0≤N≤50),如果N0&#xff0c;表示输入结束&#xff0c;这个样例不需要处理。 第二行是N个整数…...

Python环境安装

环境安装 Windows安装Linux安装 Windows安装 下载最新版Python https://www.python.org/downloads 打开安装包 选择安装路径&#xff0c;安装 安装 验证安装是否成功&#xff0c;命令行输入python Linux安装 安装依赖环境 yum install wget zlib-devel bzip2-devel op…...

苏轼在密州的四首千古名作

苏轼&#xff0c;一个从诗歌王国掉落人间的落魄贵族&#xff0c;整个政治生涯几乎都以流浪为主&#xff0c;在古诗词世界或许只有李白与之最是相似&#xff0c;不过李白的流浪属于荡歌山水、云游四方&#xff0c;而苏轼的流浪则带有被动的成分&#xff1a;一纸贬黜公文就是苏轼…...

[计算机提升] 域及域用户(组)

1.3 域及域用户(组) 1.3.1 域的概念 在Windows操作系统中&#xff0c;域&#xff08;Domain&#xff09;是指一个或多个计算机或资源的集合&#xff0c;这些计算机或资源受到单个安全数据库&#xff08;域控制器&#xff09;的管理和控制。域可以包含多个计算机、用户、组和其…...

命令行配置文件

在说具体的配置方式之前&#xff0c;我们需要首先梳理清除几个概念。这有助于我们明白自己在做什么&#xff0c;以及如何把经验平移到其他方面。 和命令行相关的有几个概念&#xff1a;terminal&#xff08;终端&#xff09;、shell&#xff08;解释器&#xff09;&#xff1b…...

MPP产品介绍-定位-应用场景-技术特点

产品定位 FusionInsight LibrA是企业级的大规模并行处理关系型数据库。FusionInsight LibrA采用MPP(Massive Parallel Processing)架构&#xff0c;支持行存储与列存储&#xff0c;提供PB(Petabyte&#xff0c;2的50次方字节)级别数据量的处理能力。 FusionInsight LibrA在核…...

Linux性能优化--性能工具:磁盘I/O

6.0 概述 本章介绍的性能工具能帮助你评估磁盘I/O子系统的使用情况。这些工具可以展示哪些磁盘或分区已被使用&#xff0c;每个磁盘处理了多少I/O,发给这些磁盘的I/O请求要等多久才被处理。 阅读本章后&#xff0c;你将能够&#xff1a; 确定系统内磁盘I/O的总量和类型(读/写…...

Archive Team: The Twitter Stream Grab

该集合不再更新&#xff0c;应被视为静态数据集。 从一般 Twitter 流中抓取的 JSON 的简单集合&#xff0c;用于研究、历史、测试和记忆的目的。这是“Spritzer”版本&#xff0c;最轻、最浅的 Twitter 抓取。不幸的是&#xff0c;我们目前无法访问流的洒水器或花园软管版本。 …...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...