1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
57.1 初学者重要提示
由于硬件JPEG解码后输出的图像格式是YCbCr,所以本章对YCbCr进行了重点介绍。 测试STM32H7硬件JPEG解码800*480图片性能,全部通过SDRAM缓存数据,解码10ms,显示9ms:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93598。 JPEG涉及到的知识点还是比较多的,如果想深入了解JPEG的话,可以看本章2.6小节给的参考资料。 本章JPEG相关概念的介绍参考了wiki百科和百度百科。 57.2 硬件JPEG基础知识 对于STM32H7的硬件JPEG了解到以下几点即可: 支持JPEG解码和编码。 对每个像素数据进行编解码只需一个时钟周期。 支持RGB、 YCbCr、YCMK和BW(灰度)图像色彩模型。 编解码时每图像分量8位深度。 57.2.1 JPEG硬件框图 认识一个外设,最好的方式就是看它的框图,方便我们快速地了解JPEG的基本功能,然后再看手册了解细节。框图如下所示: 通过这个框图,我们可以得到如下信息: JPEG硬件外设支持编码和解码 并且对于输入数据和输出数据都有FIFO支持。 jpeg_hclk 为JPEG内核和寄存器提供时钟。 jpeg_it JPEG全局中断输出。 jpeg_ift_trg JPEG输入FIFO阈值信号,可触发MDMA。 jpeg_ifnf_trg JPEG输入FIFO未满信号,可触发MDMA。 jpeg_oft_trg JPEG输出FIFO阀值信号,可触发MDMA。 jpeg_ofne_trg JPEG输出FIFO非空信号,可触发MDMA。 jpeg_oec_trg JPEG转换结束信号,可触发MDMA。 57.2.2 YCbCr颜色格式 (注,硬件JPEG解码后输出的图像格式是YCbCr,所以有必要了解下) 正如几何上用坐标空间来描述坐标集,而色彩空间用数学方式来描述颜色集。常见的3种色彩模型是RGB,CMYK和YUV。 YCbCr是YUV经过缩放和修改的翻版,只是在表示方法上不同。其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人眼对视频的Y分量更敏感,因此通过对色度分量进行子采样来减少色度分量后,人眼察觉不到的图像质量的变化。 在YUV 家族中,YCbCr 是在计算机系统中应用最多的成员,其应用领域广泛,JPEG、MPEG均采用此格式。一般人们所讲的YUV大多是指YCbCr。 57.2.3 YCbCr采样格式 YCbCr有许多取样格式,如YCbCr 4:4:4,YCbCr 4:2:2,YCbCr 4:1:1 和YCbCr 4:2:0。 4:2:0 表示每4个像素有4个亮度分量,2个色度分量 (YYYYCbCr),仅采样奇数扫描线,是便携式视频设备(MPEG-4)以及电视会议(H.263)最常用格式。 4:2:2 表示每4个像素有4个亮度分量,4个色度分量(YYYYCbCrCbCr),是DVD、数字电视、HDTV以及其它消费类视频设备的最常用格式。 4:4:4 表示全像素点阵(YYYYCbCrCbCrCbCrCbCr),用于高质量视频应用、演播室以及专业视频产品。 具体的采样方式如下图所示,以8个像素为一个单元进行采样: 由上面的截图可以了解到: 4:4:4表示Y通道,Cb+Cr通道全部采样。 4:2:2表示Y通道全部采样,而Cb+Cr通道两个像素为一组,统一采用第1个颜色值。 4:2:0表示Y通道全部采样,而Cb+Cr通道四个像素为一组,统一采用第1个颜色值。 下面是整体效果,方便大家更好的理解: 57.2.4 YCbCr的优势 RGB信号作为存储和传输的效率不高,因为它们具有大量冗余信息。而使用YCbCr可以丢弃一些信息以减少带宽,因为人的肉眼对视频的Y分量更敏感,因此通过对色度分量进行子采样来减少色度分量后,肉眼察觉不到的图像质量的变化。了解这种人为缺点,NTSC和PAL等标准大大降低了色度通道的带宽。 57.2.5 YCbCr和RGB互转 为了方便大家更好的了解YCbCr和RGB图像的实际效果,特此搜集整理了两个截图(来自WIKI百科)。下面是图像转YCBCR的效果:四个图,从上到下依次是原始图像,Y通道,Cb通道和Cr通道。 下面是一幅图像分别以R,G,B通道和Y,CB,CR通道的方式展示: 57.2.6 JPEG编解码知识 57.3 硬件JPEG的HAL库用法 JPEG的HAL库用法其实就是几个结构体变量成员的配置和使用,然后配置时钟,并根据需要配置NVIC、中断和MDMA。下面我们逐一展开为大家做个说明。 57.3.1 JPEG寄存器结构体JPEG_TypeDef JPEG相关的寄存器是通过HAL库中的结构体JPEG_TypeDef定义的,在stm32h743xx.h中可以找到它们的具体定义: typedef struct { __IO uint32_t CONFR0; __IO uint32_t CONFR1; __IO uint32_t CONFR2; __IO uint32_t CONFR3; __IO uint32_t CONFR4; __IO uint32_t CONFR5; __IO uint32_t CONFR6; __IO uint32_t CONFR7; uint32_t Reserved20[4]; __IO uint32_t CR; __IO uint32_t SR; __IO uint32_t CFR; uint32_t Reserved3c; __IO uint32_t DIR; __IO uint32_t DOR; uint32_t Reserved48[2]; __IO uint32_t QMEM0[16]; __IO uint32_t QMEM1[16]; __IO uint32_t QMEM2[16]; __IO uint32_t QMEM3[16]; __IO uint32_t HUFFMIN[16]; __IO uint32_t HUFFBASE[32]; __IO uint32_t HUFFSYMB[84]; __IO uint32_t DHTMEM[103]; uint32_t Reserved4FC; __IO uint32_t HUFFENC_AC0[88]; __IO uint32_t HUFFENC_AC1[88]; __IO uint32_t HUFFENC_DC0[8]; __IO uint32_t HUFFENC_DC1[8]; } JPEG_TypeDef; __IO表示volatile, 这是标准C语言中的一个修饰字,表示这个变量是非易失性的,编译器不要将其优化掉。core_m7.h 文件定义了这个宏: #define __O volatile /*!《 Defines ‘write only’ permissions */ #define __IO volatile /*!《 Defines ‘read / write’ permissions */ 下面我们再看JPEG的定义,在stm32h743xx.h文件。 #define PERIPH_BASE ((uint32_t)0x40000000) #define D1_AHB1PERIPH_BASE (PERIPH_BASE + 0x12000000) #define JPEG ((JPEG_TypeDef *) JPGDEC_BASE) #define JPGDEC_BASE (D1_AHB1PERIPH_BASE + 0x3000) 《----- 展开这个宏,(JPEG_TypeDef *) 0x52003000 我们访问JPEG的CR寄存器可以采用这种形式:JPEG-》CR = 0。 57.3.2 JPEG的编解码参数结构体JPEG_ConfTypeDef 此结构体用于JPEG的编解码参数,具体定义如下: typedef struct { uint8_t ColorSpace; uint8_t ChromaSubsampling; uint32_t ImageHeight; uint32_t ImageWidth; uint8_t ImageQuality; }JPEG_ConfTypeDef; 下面将这几个参数逐一为大家做个说明: uint8_t ColorSpace 此参数用于设置输出数据流中的量化表,具体支持的参数如下: #define JPEG_GRAYSCALE_COLORSPACE ((uint32_t)0x00000000U) /* 灰度(1 个量化表)*/ #define JPEG_YCBCR_COLORSPACE JPEG_CONFR1_COLORSPACE_0 /* YUV(2 个量化表) */ #define JPEG_CMYK_COLORSPACE JPEG_CONFR1_COLORSPACE /* CMYK(4 个量化表)*/ uint8_t ChromaSubsampling 此参数用于色度子采样,具体支持的参数如下: #define JPEG_444_SUBSAMPLING ((uint32_t)0x00000000U) /* 4:4:4 */ #define JPEG_420_SUBSAMPLING ((uint32_t)0x00000001U) /* 4:2:0 */ #define JPEG_422_SUBSAMPLING ((uint32_t)0x00000002U) /* 4:2:2 */ uint32_t ImageHeight 此参数用于图像高度。 uint32_t ImageWidth 此参数用于图像宽度。 uint8_t ImageQuality 此参数用于图像质量,参数范围1 – 100,1最差,100最好。 57.3.3 JPEG结构体句柄JPEG_HandleTypeDef HAL库在JPEG_TypeDef, JPEG_ConfTypeDef的基础上封装了一个结构体JPEG_HandleTypeDef,定义如下: typedef struct { JPEG_TypeDef *Instance; JPEG_ConfTypeDef Conf; uint8_t *pJpegInBuffPtr; uint8_t *pJpegOutBuffPtr; __IO uint32_t JpegInCount; __IO uint32_t JpegOutCount; uint32_t InDataLength; uint32_t OutDataLength; MDMA_HandleTypeDef *hdmain; MDMA_HandleTypeDef *hdmaout; uint8_t CustomQuanTable; uint8_t *QuantTable0; uint8_t *QuantTable1; uint8_t *QuantTable2; uint8_t *QuantTable3; HAL_LockTypeDef Lock; __IO HAL_JPEG_STATETypeDef State; __IO uint32_t ErrorCode; __IO uint32_t Context; }JPEG_HandleTypeDef; 下面将这几个参数逐一做个说明。 JPEG_TypeDef *Instance 这个参数是寄存器的例化,方便操作寄存器,详见本章3.1小节。 JPEG_ConfTypeDef Conf 这个参数是用户接触较多的,用于JPEG的编解码参数,详见本章3.2小节。 uint8_t *pJpegInBuffPtr JPEG编解码输入缓冲地址 uint8_t *pJpegOutBuffPtr JPEG编解码输出缓冲地址 __IO uint32_t JpegInCount JPEG内部输入计数。 __IO uint32_t JpegOutCount JPEG内部输出计数。 uint32_t InDataLength JPEG输入缓冲区长度,单位字节 uint32_t OutDataLength JPEG输出缓冲区长度,单位字节。 MDMA_HandleTypeDef *hdmain MDMA_HandleTypeDef *hdmaout MDMA句柄结构体指针变量,用于关联JPEG句柄,方便调用。 uint8_t CustomQuanTable 如果此参数设置为1,将使用用户设置的量化表。 uint8_t *QuantTable0; uint8_t *QuantTable1; uint8_t *QuantTable2; uint8_t *QuantTable3; 指定量化表地址。 HAL_LockTypeDef Lock __IO HAL_JPEG_STATETypeDef State __IO uint32_t ErrorCode 这三个变量主要供函数内部使用。Lock用于设置锁状态,State用于设置JPEG状态,而ErrorCode用于配置代码错误。 __IO uint32_t Context JPEG上下文。 57.3.4 JPEG初始化流程总结 使用方法由HAL库提供: 第1步:调用函数HAL_JPEG_Init进行初始化,但这个函数不需要初始化参数。 如果是JPEG编码,可以通过函数HAL_JPEG_ConfigEncoding设置JPEG图像的质量参数,质量越高,生成的JPEG文件越大、 第2步:调用编解码函数 查询式编解码函数 HAL_JPEG_Encode HAL_JPEG_Decode 中断方式 HAL_JPEG_Encode_IT HAL_JPEG_Decode_IT DMA方式 HAL_JPEG_Encode_DMA HAL_JPEG_Decode_DMA 第4步:如果用户之前的数据已经处理完毕,需要插入新数据,会调用函数HAL_JPEG_GetDataCallback (1)如果新的数据已经准备好,需要调用函数HAL_JPEG_ConfigInputBuffer。如果新的数据没有准备好,需要等待插入新数据时,可以调用函数HAL_JPEG_Pause(参数XferSelection被设置为JPEG_PAUSE_RESUME_INPUT),待数据准备好后,可以调用HAL_JPEG_ConfigInputBuffer设置新的输入缓冲和大小,然后调用函数HAL_JPEG_Resume恢复JPEG编解码。 如果编解码的数据已经处理完毕,可以调用函数HAL_JPEG_ConfigInputBuffer设置InDataLength参数为0(此函数是在回调函数HAL_JPEG_GetDataCallback里面被调用的)。 (2)函数HAL_JPEG_ConfigInputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume的工作机制允许应用程序以块为单位提供输入数据。如果新的数据块未准备好,可以调用函数HAL_JPEG_Pause暂停输入,待数据准备好后,可以调用HAL_JPEG_ConfigInputBuffer设置新的输入缓冲和大小,然后调用函数HAL_JPEG_Resume恢复JPEG编解码。 (3)新的数据块准备好后,可以在回调函数HAL_JPEG_GetDataCallback外面调用HAL_JPEG_ConfigInputBuffer 和 HAL_JPEG_Resume,但是为了保持数据一致性问题,务必在回调函数HAL_JPEG_GetDataCallback里面调用HAL_JPEG_Resume。 第5步:输出缓冲区填充了给定大小的数据后,会调用回调函数HAL_JPEG_DataReadyCallback (1)如果有数据空间存储新数据块,需要调用函数HAL_JPEG_ConfigOutputBuffer配置新存储位置。如果没有数据空间存储新数据块,需要等待有数据空间可用时,可以调用函数HAL_JPEG_Pause(参数XferSelection被设置为JPEG_PAUSE_RESUME_INPUT),待有数据空间可用时,可以调用HAL_JPEG_ConfigOutputBuffe设置新的输出缓冲,然后调用函数HAL_JPEG_Resume恢复JPEG编解码。 (2)函数HAL_JPEG_ConfigOutputBuffe/HAL_JPEG_Pause/HAL_JPEG_Resume的工作机制允许应用程序以块为单位接收数据。当接收到数据块时,应用程序可以暂停JPEG输出来处理这些数据,比如解码时YCbCr转RGB或者编码时数据存储。 (3)新的数据空间准备好后,可以在回调函数HAL_JPEG_DataReadyCallback外面调用HAL_JPEG_ConfigOutputBuffer和 HAL_JPEG_Resume,但是为了保持数据一致性问题,务必在回调函数HAL_JPEG_DataReadyCallback里面调用HAL_JPEG_Resume。 第6步:其它相关函数 JPEG解码时,如果解码成功,会调用回调函数HAL_JPEG_InfoReadyCallback。 JPEG编码操作结束后会调用回调函数HAL_JPEG_EncodeCpltCallback。 JPEG解码操作结束后,会调用回调函数HAL_JPEG_DecodeCpltCallback。 操作过程中出现错误,会调用回调函数HAL_JPEG_ErrorCallback,用户可以调用函数HAL_JPEG_GetError获取错误类型。 HAL JPEG默认使用的是ISO/IEC 10918-1规格量化表,如果要修改,可以调用函数HAL_JPEG_SetUserQuantTables实现。 通过函数HAL_JPEG_GetState可以获取JPEG状态。 57.4 源文件stm32h7xx_hal_jpeg.c 这里把我们把如下几个常用到的函数做个说明: HAL_JPEG_Init HAL_JPEG_GetInfo HAL_JPEG_Decode_DMA HAL_JPEG_ConfigInputBuffer HAL_JPEG_ConfigOutputBuffer 57.4.1 函数HAL_JPEG_Init 函数原型: HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg) { uint32_t acLum_huffmanTableAddr = (uint32_t)(&JPEG_ACLUM_HuffTable); uint32_t dcLum_huffmanTableAddr = (uint32_t)(&JPEG_DCLUM_HuffTable); uint32_t acChrom_huffmanTableAddr = (uint32_t)(&JPEG_ACCHROM_HuffTable); uint32_t dcChrom_huffmanTableAddr = (uint32_t)(&JPEG_DCCHROM_HuffTable); /* 检测句柄是否有效 */ if(hjpeg == NULL) { return HAL_ERROR; } if(hjpeg-》State == HAL_JPEG_STATE_RESET) { hjpeg-》Lock = HAL_UNLOCKED; /* 初始化GPIO,NVIC等 */ HAL_JPEG_MspInit(hjpeg); } /* 设置JPEG状态 */ hjpeg-》State = HAL_JPEG_STATE_BUSY; /* 使能JPEG */ __HAL_JPEG_ENABLE(hjpeg); /* 关闭JPEG编解码处理 */ hjpeg-》Instance-》CONFR0 &= ~JPEG_CONFR0_START; /* 关闭JPEG所有中断 */ __HAL_JPEG_DISABLE_IT(hjpeg,JPEG_INTERRUPT_MASK); /* 清空输入输入FIFO缓冲 */ hjpeg-》Instance-》CR |= JPEG_CR_IFF; hjpeg-》Instance-》CR |= JPEG_CR_OFF; /* 清除所有标志 */ __HAL_JPEG_CLEAR_FLAG(hjpeg,JPEG_FLAG_ALL); /* 初始化默认的量化表 */ hjpeg-》QuantTable0 = (uint8_t *)((uint32_t)JPEG_LUM_QuantTable); hjpeg-》QuantTable1 = (uint8_t *)((uint32_t)JPEG_CHROM_QuantTable); hjpeg-》QuantTable2 = NULL; hjpeg-》QuantTable3 = NULL; /* 初始化默认的霍夫曼表 */ if(JPEG_Set_HuffEnc_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)acLum_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcLum_huffmanTableAddr, (JPEG_ACHuffTableTypeDef *)acChrom_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcChrom_huffmanTableAddr) != HAL_OK) { hjpeg-》ErrorCode = HAL_JPEG_ERROR_HUFF_TABLE; return HAL_ERROR; } /* 使能文件头处理 */ hjpeg-》Instance-》CONFR1 |= JPEG_CONFR1_HDR; /* 复位JPEG输入输出计数 */ hjpeg-》JpegInCount = 0; hjpeg-》JpegOutCount = 0; /* 设置JPEG就绪 */ hjpeg-》State = HAL_JPEG_STATE_READY; /* 设置无错误 Reset the JPEG ErrorCode */ hjpeg-》ErrorCode = HAL_JPEG_ERROR_NONE; /* 清除上下文 */ hjpeg-》Context = 0; /* 返回HAL_OK */ return HAL_OK; } 函数描述: 此函数用于初始化JPEG。 函数参数: 第1个参数是JPEG_HandleTypeDef类型结构体指针变量,用于配置要初始化的参数,结构体变量成员的详细介绍看本章3.3小节。 返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。 注意事项: 函数HAL_JPEG_MspInit用于初始化JPEG的底层时钟、NVIC等功能。需要用户自己在此函数里面实现具体的功能。由于这个函数是弱定义的,允许用户在工程其它源文件里面重新实现此函数。当然,不限制一定要在此函数里面实现,也可以像早期的标准库那样,用户自己初始化即可,更灵活些。 如果形参hjpeg的结构体成员State没有做初始状态,这个地方就是个坑。特别是用户搞了一个局部变量JPEG_HandleTypeDef JpegHandle。 对于局部变量来说,这个参数就是一个随机值,如果是全局变量还好,一般MDK和IAR都会将全部变量初始化为0,而恰好这个 HAL_JPEG_STATE_RESET = 0x00U。 解决办法有三 方法1:用户自己初始JPEG底层。 方法2:定义JPEG_HandleTypeDef JpegHandle为全局变量。 方法3:下面的方法 if(HAL_JPEG_DeInit(&JpegHandle) != HAL_OK) { Error_Handler(); } if(HAL_JPEG_Init(&Dma2dHandle) != HAL_OK) { Error_Handler(); } 使用举例: JPEG_HandleTypeDef JPEG_Handle; JPEG_Handle.Instance = JPEG; HAL_JPEG_Init(&JPEG_Handle); 57.4.2 函数HAL_JPEG_GetInfo 函数原型: HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) { uint32_t yblockNb, cBblockNb, cRblockNb; /* 检测句柄是否有效 */ if((hjpeg == NULL) || (pInfo == NULL)) { return HAL_ERROR; } /* 读取配置参数 */ if((hjpeg-》Instance-》CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF_1) { pInfo-》ColorSpace = JPEG_YCBCR_COLORSPACE; } else if((hjpeg-》Instance-》CONFR1 & JPEG_CONFR1_NF) == 0) { pInfo-》ColorSpace = JPEG_GRAYSCALE_COLORSPACE; } else if((hjpeg-》Instance-》CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF) { pInfo-》ColorSpace = JPEG_CMYK_COLORSPACE; } pInfo-》ImageHeight = (hjpeg-》Instance-》CONFR1 & 0xFFFF0000U) 》》 16; pInfo-》ImageWidth = (hjpeg-》Instance-》CONFR3 & 0xFFFF0000U) 》》 16; if((pInfo-》ColorSpace == JPEG_YCBCR_COLORSPACE) || (pInfo-》ColorSpace == JPEG_CMYK_COLORSPACE)) { yblockNb = (hjpeg-》Instance-》CONFR4 & JPEG_CONFR4_NB) 》》 4; cBblockNb = (hjpeg-》Instance-》CONFR5 & JPEG_CONFR5_NB) 》》 4; cRblockNb = (hjpeg-》Instance-》CONFR6 & JPEG_CONFR6_NB) 》》 4; if((yblockNb == 1) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo-》ChromaSubsampling = JPEG_422_SUBSAMPLING; /*16x8 block*/ } else if((yblockNb == 0) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo-》ChromaSubsampling = JPEG_444_SUBSAMPLING; } else if((yblockNb == 3) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo-》ChromaSubsampling = JPEG_420_SUBSAMPLING; } else /* 默认是 4:4:4*/ { pInfo-》ChromaSubsampling = JPEG_444_SUBSAMPLING; } } else { pInfo-》ChromaSubsampling = JPEG_444_SUBSAMPLING; } pInfo-》ImageQuality = JPEG_GetQuality(hjpeg); /* 返回HAL_OK */ return HAL_OK; } 函数描述: 此函数主要用于解码JPEG时获取相关图像信息,比如图像质量,图像长宽等。 函数参数: 第1个参数是JPEG_HandleTypeDef类型结构体指针变量,用于配置要初始化的参数,结构体变量成员的详细介绍看本章3.3小节。 第2个参数是JPEG_ConfTypeDef类型结构体指针变量,用于获取JPEG的配置信息,结构体变量成员的详细介绍看本章3.2小 返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。 使用举例: JPEG_HandleTypeDef JPEG_Handle; JPEG_ConfTypeDef JPEG_Info; HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info); 57.4.3 函数HAL_JPEG_Decode_DMA 函数原型: HAL_StatusTypeDef HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg ,uint8_t *pDataIn ,uint32_t InDataLength ,uint8_t *pDataOutMCU ,uint32_t OutDataLength) { /* 检测参数 */ assert_param((InDataLength 》= 4)); assert_param((OutDataLength 》= 4)); /* 检测参数 */ if((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) { return HAL_ERROR; } /* 上锁 */ __HAL_LOCK(hjpeg); if(hjpeg-》State == HAL_JPEG_STATE_READY) { /* 设置JPEG忙 */ hjpeg-》State = HAL_JPEG_STATE_BUSY_DECODING; /* 设置JPEG上下文,工作在DMA界面状态 */ hjpeg-》Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); hjpeg-》Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_DMA); /* 设置输入输出缓冲地址和大小 */ hjpeg-》pJpegInBuffPtr = pDataIn; hjpeg-》pJpegOutBuffPtr = pDataOutMCU; hjpeg-》InDataLength = InDataLength; hjpeg-》OutDataLength = OutDataLength; /* 复位输入输出缓冲计数 */ hjpeg-》JpegInCount = 0; hjpeg-》JpegOutCount = 0; /* 初始化解码处理 */ JPEG_Init_Process(hjpeg); /* 启动JPEG解码处理,使用DMA方式 */ JPEG_DMA_StartProcess(hjpeg); } else { /* 解锁 */ __HAL_UNLOCK(hjpeg); return HAL_BUSY; } /* 返回HAL_OK */ return HAL_OK; } 函数描述: 此函数用于启动JPEG的DMA方式解码。 函数参数: 第1个参数是JPEG_HandleTypeDef类型结构体指针变量,用于配置要初始化的参数,结构体变量成员的详细介绍看本章3.3小节。 第2个参数是输入数据缓冲地址。 第3个参数输入数据大小,单位字节。 第4个参数是输出缓冲地址。 第5个参数是输出缓冲大小,单位字节。 返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。 使用举例: /* ********************************************************************************************************* * 函 数 名: JPEG_Decode_DMA * 功能说明: JPEG解码 * 形 参: hjpeg JPEG_HandleTypeDef句柄指针 * FrameSourceAddress 数据地址 * FrameSize 数据大小 * DestAddress 目的数据地址 * 返 回 值: HAL_ERROR表示配置失败,HAL_OK表示配置成功 * HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出 ********************************************************************************************************* */ uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint32_t FrameSourceAddress ,uint32_t FrameSize, uint32_t DestAddress) { JPEGSourceAddress = FrameSourceAddress ; FrameBufferAddress = DestAddress; Input_frameIndex = 0; Input_frameSize = FrameSize; /* 设置标志,0表示开始解码,1表示解码完成 */ Jpeg_HWDecodingEnd = 0; /* 启动JPEG解码 */ HAL_JPEG_Decode_DMA(hjpeg ,(uint8_t *)JPEGSourceAddress ,CHUNK_SIZE_IN , (uint8_t *)FrameBufferAddress ,CHUNK_SIZE_OUT); return HAL_OK; } 57.4.4 函数HAL_JPEG_ConfigInputBuffer 函数原型: void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength) { hjpeg-》pJpegInBuffPtr = pNewInputBuffer; hjpeg-》InDataLength = InDataLength; } 函数描述: 此函数用于配置编解码输入缓冲地址和数据大小。 函数参数: 第1个参数是JPEG_HandleTypeDef类型结构体指针变量,用于配置要初始化的参数,结构体变量成员的详细介绍看本章3.3小节。 第2个参数是输入缓冲地址。 第3个参数是输入缓冲大小,单位字节。 返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。 使用举例: /* ********************************************************************************************************* * 函 数 名: HAL_JPEG_GetDataCallback * 功能说明: JPEG回调函数,用于从输入地址获取新数据继续解码 * 形 参: hjpeg JPEG_HandleTypeDef 句柄指针 * NbDecodedData 上一轮已经解码的数据大小,单位字节 * 返 回 值: 无 ********************************************************************************************************* */ void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData) { uint32_t inDataLength; /* 更新已经解码的数据大小 */ Input_frameIndex += NbDecodedData; /* 如果当前已经解码的数据小于总文件大小,继续解码 */ if( Input_frameIndex 《 Input_frameSize) { /* 更新解码数据位置 */ JPEGSourceAddress = JPEGSourceAddress + NbDecodedData; /* 更新下一轮要解码的数据大小 */ if((Input_frameSize - Input_frameIndex) 》= CHUNK_SIZE_IN) { inDataLength = CHUNK_SIZE_IN; } else { inDataLength = Input_frameSize - Input_frameIndex; } } else { inDataLength = 0; } /* 更新输入缓冲 */ HAL_JPEG_ConfigInputBuffer(hjpeg,(uint8_t *)JPEGSourceAddress, inDataLength); } 57.4.5 函数HAL_JPEG_ConfigOutputBuffer 函数原型: void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength) { hjpeg-》pJpegOutBuffPtr = pNewOutputBuffer; hjpeg-》OutDataLength = OutDataLength; } 函数描述: 此函数用于配置编解码输出缓冲地址和数据大小。 函数参数: 第1个参数是JPEG_HandleTypeDef类型结构体指针变量,用于配置要初始化的参数,结构体变量成员的详细介绍看本章3.3小节。 第2个参数是输出缓冲地址。 第3个参数是输出缓冲大小,单位字节。 返回值,返回HAL_ERROR表示配置失败,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示时间溢出。 使用举例: /* ********************************************************************************************************* * 函 数 名: HAL_JPEG_DataReadyCallback * 功能说明: JPEG回调函数,用于输出缓冲地址更新 * 形 参: hjpeg JPEG_HandleTypeDef 句柄指针 * pDataOut 输出数据缓冲 * OutDataLength 输出数据大小,单位字节 * 返 回 值: 无 ********************************************************************************************************* */ void HAL_JPEG_DataReadyCallback (JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength) { /* 更新JPEG输出地址 */ FrameBufferAddress += OutDataLength; HAL_JPEG_ConfigOutputBuffer(hjpeg, (uint8_t *)FrameBufferAddress, CHUNK_SIZE_OUT); } 57.5 总结 本章节就为大家讲解这么多,JPEG功能用到的地方还是比较多的,建议熟练使用。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1767 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1069 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 00:48 , Processed in 0.820497 second(s), Total 76, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号