文章目录

  • 1.整体流程设计
  • 2.模块分析
    • 2.1 ipcm
    • 2.2 VB初始化
    • 2.3 vpss dump frame
    • 2.4 YUV420SP转RGB
      • 2.4.1 利用IVE转换出MMZ内存图像直接送给模型运算
    • 2.5 datafifo使用
    • 2.5 VO显示屏配置

1.整体流程设计

2.模块分析

2.1 ipcm

2.1.1 ipcm初始化
参考sample_msg_client 和 sample_msg_server的 Media_Msg_Init(void)函数

服务重名导致添加服务失败
开始的时候直接把sample_vio_server放在liteos上运行,运行报错

[IPCMSG]:Fun:HI_IPCMSG_AddService,Line:135,Service HiMPP_MSG already exist.
HI_IPCMSG_AddService fail

提示就是这个HiMPP_MSG已经运行了,然后就去代码里面搜索这个字符串,确实./ndk/code/mediaserver/msg/msg_server.c这个服务已经创建了同样的服务,所以只能修改咯,把服务端和客户端的 服务名+端口号都修改

2.1.2 收发消息

客户端:
HI_S32 start_server_video(){HI_S32 s32Ret=HI_FAILURE;HI_IPCMSG_MESSAGE_S *pReq = NULL;HI_IPCMSG_MESSAGE_S *pResp = NULL;pReq = HI_IPCMSG_CreateMessage(IPCM_MOD_START_CAMERA, 0, NULL, 0);HI_IPCMSG_SendSync(g_MCmsgId, pReq, &pResp, SEND_MSG_TIMEOUT);//阻塞型,等待回复消息s32Ret = pResp->s32RetVal;//取出回复的值// printf("jjcc s32Ret=%d\n",s32Ret);HI_IPCMSG_DestroyMessage(pReq);HI_IPCMSG_DestroyMessage(pResp);return s32Ret;
}
服务端:
HI_S32 MSG_Start_Camera(HI_S32 s32MsgId, HI_IPCMSG_MESSAGE_S *pstMsg)
{printf("jjcc MSG_Start_Camera\n");HI_S32 s32Ret;HI_IPCMSG_MESSAGE_S *respMsg;s32Ret = SAMPLE_VIO_StartViOnlineVpssOnlineRoute();printf("jjcc MSG_Start_Camera ret=%#x\n",s32Ret);respMsg = HI_IPCMSG_CreateRespMessage(pstMsg, s32Ret , NULL, 0);//把执行结果s32Ret 放到回复消息中HI_IPCMSG_SendAsync(s32MsgId, respMsg, NULL);HI_IPCMSG_DestroyMessage(respMsg);return HI_SUCCESS;
}

2.2 VB初始化

HI_S32 SAMPLE_VIO_StartViOnlineVpssOnlineRoute(HI_VOID)
{。。。/*config vb*/memset_s(&stVbConf, sizeof(VB_CONFIG_S), 0, sizeof(VB_CONFIG_S));stVbConf.u32MaxPoolCnt              = 2;u32BlkSize = COMMON_GetPicBufferSize(stSize.u32Width, stSize.u32Height, SAMPLE_PIXEL_FORMAT, DATA_BITWIDTH_8, COMPRESS_MODE_SEG, DEFAULT_ALIGN);stVbConf.astCommPool[0].u64BlkSize  = u32BlkSize;stVbConf.astCommPool[0].u32BlkCnt   = 10;u32BlkSize = VI_GetRawBufferSize(stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_RGB_BAYER_16BPP, COMPRESS_MODE_NONE, DEFAULT_ALIGN);stVbConf.astCommPool[1].u64BlkSize  = u32BlkSize;stVbConf.astCommPool[1].u32BlkCnt   = 4;s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);。。。

SAMPLE_COMM_SYS_Init里面就进行了VB的初始化,这里出现了报错:

[SAMPLE_COMM_SYS_Init]-381: HI_MPI_VB_Init failed!

分析步骤:
1.看log,可以看到是HI_MPI_VB_Init这个接口返回失败,一般HI_MPI接口失败的ret值,文档都会有说明,可以打印出来,查一下什么原因。我这边当时没有保存下来,现在不知道返回值是多少了。
2.查询mpp log。在linux端的命令是 cat /dev/logmpp,但是现在是运行在liteos,所以运行cat_logmpp
这边可以看到是VB申请MMZ失败。

Huawei LiteOS # cat_logmpp
<3>[(null)] mmz malloc failed!
<0>[    vb] [Func]:create_pool [Line]:252 [Info]:[size = 3136512, cnt = 10]vb mmz alloc:(null) failed!

3.查看MMZ,MMZ分为linux和liteos两端,独立的,内存分配文件是SDK根目录的.config

CONFIG_MEM_TOTAL_SIZE="512"
CONFIG_MEM_IPCM_BASE="0x80000000"
CONFIG_MEM_PARAM_BASE="0x80100000"
CONFIG_MEM_PARAM_SIZE="0x00100000"CONFIG_MEM_HUAWEILITE_SYS_BASE="0x80200000"
CONFIG_MEM_HUAWEILITE_SYS_SIZE="0x01d00000"CONFIG_MEM_RES_BASE="0x81f00000"
CONFIG_MEM_RES_SIZE="0x00100000"CONFIG_MEM_LINUX_SYS_BASE="0x82000000"
CONFIG_MEM_LINUX_SYS_SIZE="0x06000000"CONFIG_MEM_HUAWEILITE_MMZ_BASE="0x88000000"
CONFIG_MEM_HUAWEILITE_MMZ_SIZE="0x10000000"CONFIG_MEM_LINUX_MMZ_BASE="0x98000000"
CONFIG_MEM_LINUX_MMZ_ANONYMOUS_SIZE="0x03000000"
CONFIG_MEM_LINUX_MMZ_HIGO_SIZE="0x05000000"

可以看到CONFIG_MEM_HUAWEILITE_MMZ_SIZE=0x10000000=256M,CONFIG_MEM_LINUX_MMZ_=0x03000000+0x05000000=128M.
这么大还不够?
那我们看看板端实际MMZ大小。
linux端查看MMZ命令如下,可以看到是128M,符合配置。

/ # cat /proc/media-mem
+---ZONE: PHYS(0x9B000000, 0x9FFFFFFF), GFP=1, nBYTES=81920KB,    NAME="higo_mmz"
+---ZONE: PHYS(0x98000000, 0x9AFFFFFF), GFP=0, nBYTES=49152KB,    NAME="anonymous"|-MMB: phys(0x98000000, 0x9801FFFF), kvirt=0x00000000, flags=0x00000000, length=128KB,    name="TDE_MEMPOOL_MMB"---MMZ_USE_INFO:total size=131072KB(128MB),used=128KB(0MB + 128KB),remain=130944KB(127MB + 896KB),zone_number=2,block_number=1

liteos端查看MMZ命令如下,可以看到只有16M!!!

Huawei LiteOS # cat /proc/umap/media-mem
Huawei LiteOS # +---ZONE: PHYS(0x88000000, 0x88FFFFFF), GFP=0, nBYTES=16384KB,    NAME="anonymous"|-MMB: phys(0x88000000, 0x88007FFF), kvirt=0x88000000, flags=0x00000001, length=32KB,    name="sys_scale_coef"|-MMB: phys(0x88008000, 0x88023FFF), kvirt=0x88008000, flags=0x00000001, length=112KB,    name="gdc_node_buf"|-MMB: phys(0x88024000, 0x88024FFF), kvirt=0x88024000, flags=0x00000001, length=4KB,    name="GDC int_pole_co"|-MMB: phys(0x88025000, 0x88031FFF), kvirt=0x88025000, flags=0x00000001, length=52KB,    name="VGS_NodeBuf"---MMZ_USE_INFO:total size=16384KB(16MB),used=200KB(0MB + 200KB),remain=16184KB(15MB + 824KB),zone_number=1,block_number=4

我这边改了几次.config,也make clean;make all全编译,还是16M。后面报问题给海思,他们给了个命令,
make osdrv_clean;make osdrv;make drv_clean;make drv;cd reference;make samplecam_clean;make samplecam
这个命令编译出来正常,256M。可能是我环境的问题,大家如果遇到这种问题,也可以试试这个命令。

4.上面分析到是vb申请MMZ内存失败,MMZ太小的时候,由于一时没法调整大MMZ,所以分析如何减小申请的MMZ内存。
由2.2最开始的SAMPLE_VIO_StartViOnlineVpssOnlineRoute函数,可以看到申请的内存就是astCommPool[0]和astCommPool[1],由于vio_app例程能在我的板子上跑起来1280720,也是基于16M的MMZ,那为什么sample_vio这边跑1280720就不行呢?
对比sample_vio和vio_app 720P时候申请的内存
vio_app 申请 13996805+1228805=7M
sample_vio 申请 139968010+18432004=20M
sample_vio超过了16M,所以失败。为什么都是720P,sample_vio申请的空间会比vio_app大?
可以看到第一个size 1399680是一样的,只需要把个数改为5就能减小。
第二个size很大,需要把数据宽度PIXEL_FORMAT_RGB_BAYER_16BPP改为PIXEL_FORMAT_RGB_BAYER_8BPP,或者改为PIXEL_FORMAT_YVU_PLANAR_420,就会变小,申请的内存就够。

2.3 vpss dump frame

由于我们需要获取一帧数据用于人脸识别,VI-VPSS-VO整个流程里面,我们选择了VPSS这个阶段获取,因为这里能进行一些图像处理,例如放大缩小,所以就用到了HI_MPI_VPSS_GetChnFrame这个函数。
调试阶段,我们需要验证获取的帧是否正常,那么我们就在liteos端需要dump下一帧,并且保存为文件,然后电脑端用工具点开查看显示是否正常。
这里我找到了一个sdk自带的tool,amp/a7_liteos/mpp/tools/vpss_chn_dump.c,里面就有SAMPLE_MISC_VpssDump函数,负责从vpss dump一帧图像,保存yuv文件。把这个文件拷贝到我们要用到地方,然后调用这个SAMPLE_MISC_VpssDump接口。
其中会有些问题:
1.保存文件的路径 /sharefs/XXX 改为 /app/sharefs/XXX
2.需要先启动linux和liteos共享目录 /sharefs,开机后linux端运行:sharefs & ,这样共享目录就建立了。

成功获取了yuv文件之后,我们在电脑端可以用工具7yuv工具打开看。

怎么会是偏绿色,首先是怀疑摄像头驱动问题,排查了一轮没查出原因,后面配好了LCD显示屏,VO输出到显示器上,画面颜色是正常的。所以VI-VPSS-VO整个流程是没问题的,所以是我dump这边出的问题。
首先怀疑是不是数据个数读取存储出错了,用到的函数是sample_yuv_8bit_dump,对照文档YUV420SP的存储格式

sample_yuv_8bit_dump的逻辑过了一遍,也没问题。问题陷入了困境。
最后是怎么解决问题的呢?看2.4

2.4 YUV420SP转RGB

既然YUV显示偏绿色,那我dump一帧后转为RGB,再存图片看看是不是还是偏绿色咯,另外我肯定要做这个转化的,因为mtcnn模型支持的输入是RGB的。然后就了解到IVE模块支持这个颜色空间转化,HI_MPI_IVE_CSC这个接口

HI_VOID YUV2RGB(VIDEO_FRAME_S *stVFrame,cv::Mat& rgb_img )
{HI_S32 s32Ret = HI_FAILURE;
//YUV 2 RGBIVE_DST_IMAGE_S stDstData; //转换后IVE_SRC_IMAGE_S stSrcData; //转换前IVE_HANDLE hIveHandle;HI_BOOL bInstant = HI_TRUE;HI_BOOL bFinish = HI_FALSE;HI_BOOL bBlock = HI_TRUE;IVE_CSC_CTRL_S stCscCtrl;stCscCtrl.enMode = IVE_CSC_MODE_VIDEO_BT601_YUV2RGB;HI_U32 u32Size = 0;/* 颜色空间转换 */stSrcData.enType = IVE_IMAGE_TYPE_YUV420SP;   //广义图像的物理地址数组stSrcData.au64PhyAddr[0] = stVFrame->u64PhyAddr[0];  //0stSrcData.au64PhyAddr[1] = stVFrame->u64PhyAddr[1];  //stSrcData.au64VirAddr[0] = stVFrame->u64VirAddr[0];  //0stSrcData.au64VirAddr[1] = stVFrame->u64VirAddr[1];  //stSrcData.au32Stride[0] = stVFrame->u32Stride[0];  //stSrcData.au32Stride[1] = stVFrame->u32Stride[1];  //stSrcData.u32Width   = stVFrame->u32Width;//stSrcData.u32Height  = stVFrame->u32Height; //stDstData.enType = IVE_IMAGE_TYPE_U8C3_PACKAGE;stDstData.u32Width   = stSrcData.u32Width; //高宽同stSrcDatastDstData.u32Height  = stSrcData.u32Height;stDstData.au32Stride[0]  = stVFrame->u32Stride[0]; //stDstData.au32Stride[1]  = stVFrame->u32Stride[1];stDstData.au32Stride[2]  = stVFrame->u32Stride[2];u32Size = stDstData.au32Stride[0] * stDstData.u32Height * 3;s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&stDstData.au64PhyAddr[0], (HI_VOID**)&stDstData.au64VirAddr[0], "User", HI_NULL, u32Size);  //if(HI_SUCCESS != s32Ret){HI_MPI_SYS_MmzFree(stSrcData.au64PhyAddr[0], (HI_VOID**)stSrcData.au64VirAddr[0]);return;}memset((HI_VOID**)stDstData.au64VirAddr[0], 0, u32Size);s32Ret = HI_MPI_SYS_MmzFlushCache(stDstData.au64PhyAddr[0], (HI_VOID**)stDstData.au64VirAddr[0], u32Size);if(HI_SUCCESS != s32Ret){       printf("HI_MPI_SYS_MmzFlushCache FAILED,s32Ret=%#x\n",s32Ret);HI_MPI_SYS_MmzFree(stDstData.au64PhyAddr[0], (HI_VOID**)stDstData.au64VirAddr[0]);return;}/* 颜色空间转换 */s32Ret = HI_MPI_IVE_CSC(&hIveHandle,&stSrcData,&stDstData,&stCscCtrl,bInstant);if(HI_SUCCESS != s32Ret){       printf("HI_MPI_IVE_CSC FAILED,s32Ret=%#x\n",s32Ret);HI_MPI_SYS_MmzFree(stDstData.au64PhyAddr[0], (HI_VOID**)stDstData.au64VirAddr[0]);return;}s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock);while(HI_ERR_IVE_QUERY_TIMEOUT == s32Ret){usleep(100);s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock);}
//=====================================================================rgb_img.create(stVFrame->u32Height, stVFrame->u32Width, CV_8UC3);memcpy(rgb_img.data, (unsigned char*)stDstData.au64VirAddr[0], u32Size);HI_MPI_SYS_MmzFree(stDstData.au64PhyAddr[0], (HI_VOID**)stDstData.au64VirAddr[0]);
}

之前我不明白为什么au64PhyAddr明明是定义了[3] 有三个的,为什么只赋值了0,1。这个可以看2.2上面YUV420SP的存储结构,Y存了一组,UV合在一起存在一组。另外由于是4:2,所以总的数据长度是Y长度的3/2。
好了这个接口在liteos上运行起来又出问题了:
HI_MPI_IVE_CSC失败,返回 0xa01d8010,对照文档查询就是:系统没有初始化或者没有加载相应的模块。
再在liteos初始化的文件里面搜索IVE初始化相关的代码。

找到了,ive模块初始化接口被SVP_BIND_LITEOS控制了,这个宏就是说SVP部署在liteos端还是linux端,默认是部署在linux端的,我们识别算法也是跑在linux端的,所以,,,,liteos端没有IVE,,,所以只能把这个转化的动作放在linux端来做了。
后面打通了datafifo之后,把YUV数据传到了linux,转为了RGB之后,颜色正常!!!,再看转RGB之前的YUV,颜色也正常!!!dump的函数和liteos端一模一样,可是出来的图片颜色不一样,好吧,不关我代码的事情了。

2.4.1 利用IVE转换出MMZ内存图像直接送给模型运算

检测模型有forward(cv::Mat &mat_img)接口,Mat图片需要转化为mmz内存传给模型Blob。需要增加forward(MMZIMG *mmz_img)接口,加速检测

问题:
mmz图像检测失败。摄像头传过来的YUV图像经过IVE转化为BGR图像后,一份拷贝给Mat,一份直接把mmz指针传给mmz_img。进入forward后,分别打印mmz_img.VirAddr数据和mat_img.data数据是一样的,可是只有后者能检测到人脸,前者检测不到。
定位问题:
forward传入的参数数据是一样的,打印实际模型输入Blob不一样,那就是img——Blob出现了异常。
原因:
Mat2Blob用的不是mat.data赋值,而是mat.atcv::Vec3b(h, w)[c]方式。
由下图Mat像素存储分布看,mat.data取值是顺序逐个逐个取,也就是BGRBGRBGR(rgb_package格式)。而后者取值方式是按通道取值,是BBBGGGRRR(rgb_planar格式)。所以mmz_img图像检测失败的原因就是数据顺序不对。
解决方法:mmz_img进行像素顺序调整后送入模型forward,问题解决。

然而,利用指针逐个调整mmz_img像素顺序,耗时较大。
继续分析优化,阅读IVE文档,发现如下说明:


看来IVE是支持这两种格式的,是否YUV2RGB就能直接转换出rgb_planar呢?答案是可以的。
只要配置:
stCscCtrl.enMode=IVE_CSC_MODE_PIC_BT601_YUV2RGB
stSrcData.enType=IVE_IMAGE_TYPE_YUV420SP
stDstData.enType=IVE_IMAGE_TYPE_U8C3_PLANAR
另外要注意:
如果使用IVE_IMAGE_TYPE_U8C3_PACKAGE,则stDstData只需要配置1组地址,因为package格式输出是BGRBGRBGR,只需要一个起始指针就行了
stDstData.au64PhyAddr[0]
stDstData.au64VirAddr[0]
如果使用IVE_IMAGE_TYPE_U8C3_PLANAR,则stDstData只需要配置3组地址,因为planar格式输出是分开3通道,分别存B,G,R,需要3通道地址。
stDstData.au64PhyAddr[0],stDstData.au64PhyAddr[1],stDstData.au64PhyAddr[2]
stDstData.au64VirAddr[0],stDstData.au64VirAddr[1],stDstData.au64VirAddr[2]
否则会出现HI_MPI_IVE_CSC 0xa01d8003 参数非法的报错。

2.5 datafifo使用

2.4最后提到,需要把从VPSS获取的一帧图像,传到linux端处理,这就要用到datafifo了。
先去看官方文档:《HiSysLink API 开发参考.pdf》
了解完原理之后就看看SDK的demo代码:
amp/a7_liteos/mpp/sample/common/media_msg/client/sample_msg_venc.c
amp/a7_liteos/mpp/sample/common/media_msg/server/sample_msg_venc.c
里面就有客户端和服务端的datafifo启动,写数据,读数据逻辑。

之前出现过个问题,运行一段时间之后,客户端会报错:

==========================getOneFrame==========================
jjccmmz_userdev:ioctl_mmb_alloc:  getOneFrame
jjcc pu64PhyAddr=2291351552,g_DatafifoHandle=2291351552,readLen=328
[Func]:HI_MPI_SYmmz_userdev:get_mmbinfo_safe: S_MmzAlloc_Cached [Line]:936 [Info]:System alloc mmz memory failed!
HI_MPI_SYS_MmzAlloc_Cached FAILED,s32Ret=0xffffffff
[Func]:HI_MPI_SYS_MmzFree [Line]:969 [Info]:System unmap mmz memory failed!
HI_MPI_SYS_MmzFree,s32Ret=0xffffffff

又是MMZ内存失败,通过linux端查看mmz命令:cat /proc/media-mem 发现,MMZ剩余空间逐渐变小,原来是出现了内存泄漏,后面查到是调用了HI_MPI_SYS_MmzAlloc_Cached结束后没有调用HI_MPI_SYS_MmzFree释放空间,修复了就好了。

2.5 VO显示屏配置

1.对于vio_app例程来说
屏幕初始化流程:https://www.cnblogs.com/linhaostudy/p/11077703.html
屏幕驱动路径:amp/a7_liteos/drv/extdrv/screen/st7789/libhi_ssp_st7789.a
加载屏幕驱动:reference/samplecam/modules/init/amp/liteos/Makefile

else ifeq ($(CONFIG_SCREEN_ST7789),y)
VSS_LIB += -lhi_ssp_st7789 -lhalscreen_st7789_server

.config配置屏幕类型

CONFIG_SCREEN_ST7789=y

app初始化屏幕:
reference/samplecam/app/vio/vio_main.c

VIO_LcdPreviewHI_HAL_SCREEN_Register(HI_HAL_SCREEN_IDX_0, &stHALSCREENObj)

stHALSCREENObj来自于reference/hal/screen/st7789/hal_screen_st7789.c

HI_HAL_SCREEN_OBJ_S stHALSCREENObjHAL_SCREEN_ST7789_GetAttr

2.对于sample_viol例程

/*config vo*/SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);stVoConfig.enDstDynamicRange = enDynamicRange;stVoConfig.enVoIntfType = VO_INTF_LCD_6BIT;stVoConfig.enIntfSync = VO_OUTPUT_240x320_50;stVoConfig.enPicSize = enPicSize;//HI_MPI_VO_SetChnRotation(stVoConfig.VoDev,0,ROTATION_90);//旋转/*start vo*/s32Ret = SAMPLE_COMM_VO_StartVO(&stVoConfig);/*vpss bind vo*/s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp, VpssChn, stVoConfig.VoDev, VoChn);

HI3559V200获取IMX458摄像头数据_(3)实例分析+问题解决相关推荐

  1. HI3559V200获取IMX458摄像头数据_(2)sdk例程sample_vio

    文章目录 1.sample_vio介绍 1 linux client端 2 liteos server端 2.sample_vio_server如何在liteos运行 1.如何将sample_vio_ ...

  2. HI3559V200获取IMX458摄像头数据_(1)基本逻辑

    文章目录 背景 无法使用USB摄像头 MPP架构,vi-vpss-vo 为什么要用liteos ipcm通信 背景 平台:HI3559V200 DEMO板 目的:从摄像头获取图像,进行人脸检测和识别. ...

  3. Kinect开发之获取彩色摄像头数据

    刚接触到Kinect,简要地介绍一下其摄像头相关的结构功能: Kinect 有两类摄像头,近红外摄像头和普通的视频摄像头.视频摄像头提供了一般摄像 头类似的彩色影像.这种数据流是三中数据流中使用和设置 ...

  4. java获取网络摄像头数据

    1,基于ffmpeg封装类 <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform --><depe ...

  5. 怎么获取codeforces的数据_手把手教你学会新媒体运营——如何通过数据分析来优化新媒体运营...

    一般来说,我们希望运营的新媒体的每篇内容都可以获得高打开率和高分享率.但事实并不总是如愿,因此,在新媒体运营过程当中,我们需要不断地优化自身内容,以求可以获得更多的关注和流量.那么我们今天来讨论下如何 ...

  6. Request_获取请求行数据_方法介绍

    request功能:     1. 获取请求消息数据         1. 获取请求行数据             * GET /day14/demo1?name=zhangsan HTTP/1.1 ...

  7. android 简单获取实时天气数据_绘图本身很简单但是获取数据很难

    看到我们生信技能树的教学群有学员提问这样的图如何绘制: 其实我们讲解过,绘图代码本身搜索即可拿到,关键词 ggpubr paired boxplot ,输入到 https://cn.bing.com/ ...

  8. clistctrl获取选中行数据_自动化报表——课程3:数据清洗

    第三节课我们学习Power Query数据清洗. 实际上,不管你是否用到Power BI,只要你和数据打交道,都应该学会Power Query.作为Excel近年来的伟大发明,Power Query被 ...

  9. Unity体感应用开发——Kinect V2 获取彩色摄像头数据

    硬件准备 使用Kinect 第二代传感器开发体感应用,一定要买的是kinect for windows,也就是带有转换器的套装. 即不光要有 长250mm*宽85mm*高65mm 还要有 算上for ...

最新文章

  1. python怎么字体加阴影_如何添加阴影到tkinter帧?
  2. PowerDesigner中为Oracle添加自增id
  3. 让windows 2003启动后直接进入桌面
  4. 基础算法学习(二)_二叉树及应用赫夫曼编码
  5. 常程加盟小米,“电磁炉”组合出道,网友喊话雷军也接收一下罗永浩!
  6. php如何判断是否关注,微信公众号判断用户是否已关注php代码解析
  7. jdbc mysql 存储过程执行失败_JDBC连接执行MySQL存储过程报空指针或权限错误
  8. mysql 主从复制 表结构_MySQL主从复制-双主结构
  9. 【干货】从0到1打造企业数字化运营闭环白皮书.pdf(附下载链接)
  10. C++ string与vectorfloat类型相互转换之stringstream
  11. 比赛计分软件部分界面抓图
  12. iText生成pdf带目录
  13. Python报错记录之“list indices must be integers or slices, not str”
  14. 使用ffmpeg对视频、图片进行旋转,上下翻转,水平翻转
  15. 触控板用不了,解决办法:
  16. 婆媳矛盾引发小夫妻动手 女子抄尖刀刺死丈夫
  17. javascript制作gif动图----gif.js
  18. 网络视频监控系统的现状和发展
  19. 3、JavaWeb中Service层的作用、MyBatis的重要组件、mybatis-config.xml中的别名映射、properties配置、#{}和${}的区别、获取插入数据的主键值
  20. Rosalind Java|Inferring mRNA from Protein

热门文章

  1. mysql用c语言连接驱动程序,C语言连接MySql数据库
  2. LaTeX学习经验分享
  3. 必应搜索留痕外推霸屏
  4. html 判断页面加载完成,Javascript判断页面是否加载完成
  5. miniui不显示textbox边框_新品发布艺卓推出31.5英寸4K超高清大屏幕显示器:EV3285...
  6. 塑胶模具2D排位图步骤及注意事项,给新手普及一下
  7. java财务管理项目_基于jsp的个人财务管理-JavaEE实现个人财务管理 - java项目源码...
  8. 祖玛游戏源码:——天地会
  9. 十六届全向组算法开源(二)
  10. windows ce 安装java,Windows环境下JDK安装和配置