硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5966|回复: 17
收起左侧

[HAL学习笔记] HAL库的硬件JPEG源文件stm32h7xx_hal_jpeg.c学习笔记(2019-05-01 V1.0)

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2019-5-1 00:57:39 | 显示全部楼层 |阅读模式
==============================================================================
                                                                   ##### 如何使用此驱动  #####
==============================================================================

1、调用函数HAL_JPEG_Init进行初始化,但这个函数不需要初始化参数。

2、如果是JPEG编码,可以通过函数HAL_JPEG_ConfigEncoding设置JPEG图像的质量参数,质量越高,生成的JPEG文件越大。

3、查询式编解码函数
HAL_JPEG_Encode
HAL_JPEG_Decode

中断方式
HAL_JPEG_Encode_IT
HAL_JPEG_Decode_IT

DMA方式
HAL_JPEG_Encode_DMA
HAL_JPEG_Decode_DMA

4、JPEG解码时,如果解码成功,会调用回调函数HAL_JPEG_InfoReadyCallback。

5、JPEG编解码期间会调用函数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。

6、输出缓冲区填充了给定大小的数据后,会调用回调函数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。

7、JPEG编码操作结束后会调用回调函数HAL_JPEG_EncodeCpltCallback。

8、JPEG解码操作结束后,会调用回调函数HAL_JPEG_DecodeCpltCallback。

9、操作过程中出现错误,会调用回调函数HAL_JPEG_ErrorCallback,用户可以调用函数HAL_JPEG_GetError获取错误类型。

10、HAL JPEG默认使用的是ISO/IEC 10918-1规格量化表,如果要修改,可以调用函数HAL_JPEG_SetUserQuantTables实现。

11、通过函数HAL_JPEG_GetState可以获取JPEG状态

12、
(+) __HAL_JPEG_RESET_HANDLE_STATE : Reset JPEG handle state.
(+) __HAL_JPEG_ENABLE             : Enable the JPEG peripheral.
(+) __HAL_JPEG_DISABLE            : Disable the JPEG peripheral.
(+) __HAL_JPEG_GET_FLAG           : Check the specified JPEG status flag.
(+) __HAL_JPEG_CLEAR_FLAG         : Clear the specified JPEG status flag.
(+) __HAL_JPEG_ENABLE_IT          : Enable the specified JPEG Interrupt.
(+) __HAL_JPEG_DISABLE_IT         : Disable the specified JPEG Interrupt.
(+) __HAL_JPEG_GET_IT_SOURCE      : returns the state of the specified JPEG Interrupt (Enabled or disabled).



初始化和复位初始化函数
HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg);
HAL_StatusTypeDef HAL_JPEG_DeInit(JPEG_HandleTypeDef *hjpeg);
void HAL_JPEG_MspInit(JPEG_HandleTypeDef *hjpeg);
void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef *hjpeg);

编解码配置函数
HAL_StatusTypeDef HAL_JPEG_ConfigEncoding(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pConf);
HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo);
HAL_StatusTypeDef HAL_JPEG_EnableHeaderParsing(JPEG_HandleTypeDef *hjpeg);
HAL_StatusTypeDef HAL_JPEG_DisableHeaderParsing(JPEG_HandleTypeDef *hjpeg);
HAL_StatusTypeDef HAL_JPEG_SetUserQuantTables(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable0, uint8_t *QTable1, uint8_t *QTable2, uint8_t *QTable3);

JPEG编解码处理函数
HAL_StatusTypeDef  HAL_JPEG_Encode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, uint8_t *pDataOut, uint32_t OutDataLength, uint32_t Timeout);
HAL_StatusTypeDef  HAL_JPEG_Decode(JPEG_HandleTypeDef *hjpeg ,uint8_t *pDataIn ,uint32_t InDataLength ,uint8_t *pDataOutMCU ,uint32_t OutDataLength, uint32_t Timeout);
HAL_StatusTypeDef  HAL_JPEG_Encode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, uint8_t *pDataOut, uint32_t OutDataLength);
HAL_StatusTypeDef  HAL_JPEG_Decode_IT(JPEG_HandleTypeDef *hjpeg ,uint8_t *pDataIn ,uint32_t InDataLength ,uint8_t *pDataOutMCU ,uint32_t OutDataLength);
HAL_StatusTypeDef  HAL_JPEG_Encode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, uint8_t *pDataOut, uint32_t OutDataLength);
HAL_StatusTypeDef  HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg ,uint8_t *pDataIn ,uint32_t InDataLength ,uint8_t *pDataOutMCU ,uint32_t OutDataLength);
HAL_StatusTypeDef  HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection);
HAL_StatusTypeDef  HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection);
void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength);
void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength);
HAL_StatusTypeDef HAL_JPEG_Abort(JPEG_HandleTypeDef *hjpeg);


回调函数
void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef *hjpeg,JPEG_ConfTypeDef *pInfo);
void HAL_JPEG_EncodeCpltCallback(JPEG_HandleTypeDef *hjpeg);
void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef *hjpeg);
void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef *hjpeg);
void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData);
void HAL_JPEG_DataReadyCallback (JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength);

中断处理函数
void HAL_JPEG_IRQHandler(JPEG_HandleTypeDef *hjpeg);


状态和错误获取函数
HAL_JPEG_STATETypeDef  HAL_JPEG_GetState(JPEG_HandleTypeDef *hjpeg);
uint32_t              HAL_JPEG_GetError(JPEG_HandleTypeDef *hjpeg);

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
 楼主| 发表于 2019-5-1 01:59:02 | 显示全部楼层
整理完毕。
回复

使用道具 举报

0

主题

13

回帖

13

积分

新手上路

积分
13
发表于 2019-5-4 08:47:25 | 显示全部楼层
不错,加油      。
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-11 14:40:28 | 显示全部楼层
最近在搞硬件jpeg,跟着安富莱的文档对jpeg进行了配置,可是死在了解码上,一直在解码,那个标志位不会变为1.我的图像是jpg使用software变为c数组(rgb类的),不知道啥问题,硬汉哥有啥建议吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
 楼主| 发表于 2021-3-11 15:57:58 | 显示全部楼层
wangertan 发表于 2021-3-11 14:40
最近在搞硬件jpeg,跟着安富莱的文档对jpeg进行了配置,可是死在了解码上,一直在解码,那个标志位不会变为 ...

注意这个问题没

测试发现STM32H7的硬件JPEG不支持渐进式JPEG文件解析,Baseline标准型没问题
http://www.armbbs.cn/forum.php?m ... 3583&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-11 18:26:17 | 显示全部楼层
eric2013 发表于 2021-3-11 15:57
注意这个问题没

测试发现STM32H7的硬件JPEG不支持渐进式JPEG文件解析,Baseline标准型没问题

好的 我看下是不是这个问题
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-12 08:49:47 | 显示全部楼层
wangertan 发表于 2021-3-11 18:26
好的 我看下是不是这个问题

刚才看了下,图片是标准型的 240*320
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-12 16:44:36 | 显示全部楼层
wangertan 发表于 2021-3-12 08:49
刚才看了下,图片是标准型的 240*320

我现在参考你给的那个连接 下载了网盘里的硬件jpeg工程,参考后发现可以进入解码完成回调函数了。你的工程里的图片是480*272的,我的lcd是240*320的,要是我自己找图片转换为数组应该也是可以的。但是我试了下,使用cube给的软件进行转换,但是我不知道该选择转换为那种格式,我试的是565但是好像不行。换成自己转换得到的数组就进入不了解码完成回调函数。还有 void DMA2D_Copy_YCbCr_To_RGB(uint32_t *pSrc,
uint32_t *pDst,
uint16_t x,
uint16_t y,
uint16_t xsize,
uint16_t ysize,
uint32_t PixelFormat,
uint32_t ChromaSampling);这个函数里的lcd_width该是多少呢,我看了你的工程写的是400,要是240*320这个值该怎么设置。硬汉哥有什么建议吗?
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-12 17:24:30 | 显示全部楼层
wangertan 发表于 2021-3-12 16:44
我现在参考你给的那个连接 下载了网盘里的硬件jpeg工程,参考后发现可以进入解码完成回调函数了。你的工 ...

我使用HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info); 函数时,屏的尺寸为480*272,我的lcd是240*320,这个参数在哪里改,是这样 JPEG_Handle.Instance->CONFR1=240;  JPEG_Handle.Instance->CONFR3 =320改的吗?
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-12 18:29:48 | 显示全部楼层
wangertan 发表于 2021-3-12 17:24
我使用HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info); 函数时,屏的尺寸为480*272,我的lcd是240*320,这 ...

刚又仔细看了下,发现现在自己生成的图片也可以把程序完整的执行下来,但是在lcd显示的时候就乱了(一点也看不出图像),显示出错。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
 楼主| 发表于 2021-3-13 09:11:00 | 显示全部楼层
wangertan 发表于 2021-3-12 16:44
我现在参考你给的那个连接 下载了网盘里的硬件jpeg工程,参考后发现可以进入解码完成回调函数了。你的工 ...

貌似你看错了,我的程序里面没有400,我的是g_LcdWidth,就是你的显示屏宽度
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-13 10:13:18 | 显示全部楼层
本帖最后由 wangertan 于 2021-3-13 10:55 编辑
eric2013 发表于 2021-3-13 09:11
貌似你看错了,我的程序里面没有400,我的是g_LcdWidth,就是你的显示屏宽度

是的 我看错了。现在是可以 while(Jpeg_HWDecodingEnd == 0)
  {}通过这一步了,但是最终显示出来的数据和我的原图像不一样,就像花屏了一样。调试看了下,我的sram刚开始是有初始值的,经过JPEG_Decode_DMA()之后,sram里的数据没变化。
        我的lcd是240*320的,我还要修改其他参数吗?        
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-13 11:15:32 | 显示全部楼层
eric2013 发表于 2021-3-13 09:11
貌似你看错了,我的程序里面没有400,我的是g_LcdWidth,就是你的显示屏宽度

我没有对sram进行分块 我是将解码的数据放在了sram里,定义了一个数组存放要显示的数据,现在可以正常显示了。
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-13 11:16:43 | 显示全部楼层
另外,我想问下咱们又编码的代码吗?要是没有自己该怎么做。
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-13 14:16:43 | 显示全部楼层
现在解码完全可以了,显示的图像跟原来的一样。就是有一点疑惑的是,我跟着你给的工程配置的dma2d是存储器到存储器,并且执行fpc颜色格式转换。但是我的可以的是:解码得到的数据存放在sram里,显示数据要是放在sram里就会错乱,只好定义内部数组,这样才可以正常显示,难道说内部定义的数组也是存储器吗?(对内存不太懂)。安富莱有提供编码的工程吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
 楼主| 发表于 2021-3-14 07:02:55 | 显示全部楼层
wangertan 发表于 2021-3-13 14:16
现在解码完全可以了,显示的图像跟原来的一样。就是有一点疑惑的是,我跟着你给的工程配置的dma2d是存储器 ...

你的描述不太清晰,需要你准确表达SRAM是什么,占用那个地址空间,是否程序占用了这个空间。

你定义内部数组又是什么,占用那个空间。
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2021-3-15 08:33:13 | 显示全部楼层
感谢分享,顶起来。
Releasing your creativity
回复

使用道具 举报

2

主题

38

回帖

44

积分

新手上路

积分
44
发表于 2021-3-15 08:37:46 | 显示全部楼层
eric2013 发表于 2021-3-14 07:02
你的描述不太清晰,需要你准确表达SRAM是什么,占用那个地址空间,是否程序占用了这个空间。

你定义内 ...

sram是外加的保存变量的 内部就是内部flash
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-5 17:53 , Processed in 0.372713 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表