硬汉嵌入式论坛

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

[JPEG] RTOS中使用libjpeg解码jpg图片失败

[复制链接]
回帖奖励 4 个金币 回复本帖可获得 1 个金币奖励! 每人限 1 次

3

主题

7

回帖

16

积分

新手上路

积分
16
发表于 2024-10-25 01:57:12 | 显示全部楼层 |阅读模式
使用STM32H743XIH6,使用RTOS加libjpeg,cubemx配置的工程,libjpeg一直会报JERR_BAD_HUFF_TABLE错误。将libjpeg移出rtos环境,即仍然运行rtos,但解码工作不放在rtos任务里,放在中断里,就可以正常运行。

初步判断是rtos里面的libjpeg进行运算的时候出了问题,有没有大神给个方向指点一下应该给rtos配置什么选项。
libjpeg应该是没有使用浮点数计算的,所以应该不是rtos浮点计算的原因。

附上解码函数代码,是在运行到 jpeg_start_decompress(&cinfo); 出的问题,更具体的是在jdhuff.c的第437行

[C] 纯文本查看 复制代码
void decode_jpeg_to_rgb(uint8_t *jpeg_data, uint32_t jpeg_size, uint8_t *rgb_buffer)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    // 初始化 JPEG 解压缩结构体
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    // 设置内存源
    jpeg_mem_src(&cinfo, jpeg_data, jpeg_size);

    // 读取 JPEG 头部信息
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);

    // 设置 RGB 输出缓冲区
    int row_stride = cinfo.output_width * cinfo.output_components; // 每行字节数
    // uint8_t *row_buffer = (uint8_t *)pvPortMalloc(row_stride);
    uint8_t *row_buffer = (uint8_t *)malloc(row_stride);

    // 逐行读取解码后的图像数据
    for (int y = 0; y < cinfo.output_height; y++)
    {
        jpeg_read_scanlines(&cinfo, &row_buffer, 1);
        for (int x = 0; x < cinfo.output_width; x++)
        {
            uint8_t r = row_buffer[x * cinfo.output_components + 0];
            uint8_t g = row_buffer[x * cinfo.output_components + 1];
            uint8_t b = row_buffer[x * cinfo.output_components + 2];
            uint16_t value = rgb888_to_rgb565(r, g, b);
            rgb_buffer[2 * y * cinfo.output_width + x * 2] = (value & 0xff);
            rgb_buffer[2 * y * cinfo.output_width + x * 2 + 1] = ((value & 0xff00) >> 8);
        }
    }

    // 清理资源
    // vPortFree(row_buffer);
    free(row_buffer);
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-10-25 09:04:33 | 显示全部楼层

回帖奖励 +1 个金币

软件libjpeag没有用,硬件JPEG解码弄了,可供参考

V7-529_emWin6.x实验_JPEG图片显示(裸机硬解方式).7z (7.67MB)
V7-530_emWin6.x实验_JPEG图片显示(RTOS硬解方式).7z (7.99MB)
回复

使用道具 举报

3

主题

7

回帖

16

积分

新手上路

积分
16
 楼主| 发表于 2024-10-26 21:23:24 | 显示全部楼层
在h723上就可以正常运行
等找到问题了再来更新一下。
另:软件解码真的好慢,9kb的800*480大小的图片要255ms来解码,还是用硬件吧
回复

使用道具 举报

3

主题

7

回帖

16

积分

新手上路

积分
16
 楼主| 发表于 2024-10-27 21:18:30 | 显示全部楼层
找到问题了,是sdram字节对齐问题,将memcpy换成自己的单字节拷贝函数就没问题了。
编译器自动优化memcpy为4字节拷贝导致memcpy的时候没有拷贝正确,没触发硬件中断,但是拷贝后数据不对。
目前没有找到什么好的方法,将MPU改为normal只是不报错,拷贝的时候数据还是不对。
相关链接参见论坛:
https://forum.anfulai.cn/forum.p ... age=1&mobile=no
https://forum.anfulai.cn/forum.p ... 9400&fromuid=58
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-10-28 00:55:01 | 显示全部楼层
苏瓦奥术 发表于 2024-10-27 21:18
找到问题了,是sdram字节对齐问题,将memcpy换成自己的单字节拷贝函数就没问题了。
编译器自动优化memcpy ...

复制前调用下函数SCB_CleanInvalidateDCache试试
回复

使用道具 举报

3

主题

7

回帖

16

积分

新手上路

积分
16
 楼主| 发表于 2024-10-28 23:32:52 | 显示全部楼层
破案了,在使用cube创建工程的时候没有打开Cache,汗流浃背
如此同时还有一个疑问,在没开cache时,为什么放到0x24000000内存就没事,放到sdram里就有事

https://forum.anfulai.cn/forum.p ... 9400&fromuid=58帖子中的第10条,
就这种情况而言(memcpy中源地址和目标地址至少有一个不是对齐的),AXI RAM和SDRAM应该是差不多的吧

我也没给0x24000000开mpu,反而倒是给sdram开了mpu。
莫不成凑巧在0x24000000那段都是对齐的?内存分配都是rtos管理的
等有时间去debug调试看看
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-10-29 09:18:38 | 显示全部楼层
苏瓦奥术 发表于 2024-10-28 23:32
破案了,在使用cube创建工程的时候没有打开Cache,汗流浃背
如此同时还有一个疑问,在没开cache时,为什 ...

RTOS的话,可以多申请3个字节,对齐下处理,或者MPU/Cache处理,均可。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 17:35 , Processed in 0.040442 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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