MPP Zlib 设计及接口说明
2 Dec 2024
Read time: 4 minute(s)
MPP zlib 的功能:利用硬件加速解压 zlib 文件。
接口设计
mpp_zlib_uncompressed
函数原型 |
int mpp_zlib_uncompressed(unsigned char
*compressed_data,unsigned int compressed_len,
unsigned char *uncompressed_data,unsigned int
uncompressed_len);
|
---|---|
功能说明 | 解压 zlib 文件 |
参数定义 |
compressed_data - 压缩数据起始地址
compressed_len - 压缩数据长度
uncompressed_data - 存放解压数据 buffer 的起始地址
uncompressed_len - 存放解压数据 buffer 的长度
|
返回值 | >0,解压数据实际长度; <0,失败 |
注意事项 |
compressed_data - 16 byte 对齐,填充数据后,需要刷 cache
compressed_len - 实际有效数据长度
uncompressed_data - 8 byte 对齐,获取数据前,先清掉 cache
uncompressed_len - 8 byte 对齐,必须大于等于解压数据实际长度
|
参考 Demo
#include "dfs.h"
#include "unistd.h"
#include "mpp_zlib.h"
#include "mpp_mem.h"
#include "mpp_log.h"
#include <console.h>
#include "aic_core.h"
static void print_help(char *program)
{
printf("Compile time: %s\n", __TIME__);
printf("usage:%s input_file out_file out_put_buffer_len \n", program);
printf("note:out_put_buffer_len ≥ out_file_size \n");
printf("exsample:%s readme.zlib readme.txt 204800\n",program);
}
int zlib_test(int argc,char **argv)
{
int ret = 0;
int fd_in = 0;
int fd_out = 0;
int file_len;
int in_len_align;
int out_len;
int out_len_align;
int r_len=0,w_len=0;
int uncompress_len;
unsigned long in_buff = 0;;
unsigned long in_buff_align;
unsigned long out_buff = 0;
unsigned long out_buff_align;
int align;
unsigned int before;
unsigned int after;
if (argc != 4) {
print_help(argv[0]);
return -1;
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in < 0) {
loge("open %s fail\n",argv[1]);
return -1;
}
file_len = lseek(fd_in, 0, SEEK_END);
lseek(fd_in, 0, SEEK_SET);
#define INPUT_BUFFER_ALIGN 16
if (CACHE_LINE_SIZE > INPUT_BUFFER_ALIGN) {
align = CACHE_LINE_SIZE;
} else {
align = INPUT_BUFFER_ALIGN;
}
//input buffer len align max of {CACHE_LINE_SIZE,INPUT_BUFFER_ALIGN}
in_len_align = (file_len+align-1)/align*align;
in_buff = (unsigned long)aicos_malloc(MEM_CMA, in_len_align+align-1);
if (in_buff == 0) {
loge("mpp_alloc fail\n");
ret = -1;
goto _exit;
}
//input buffer addr align max of {CACHE_LINE_SIZE,INPUT_BUFFER_ALIGN}
in_buff_align = ((in_buff+align-1)&(~(align-1)));
r_len = read(fd_in,(void *)in_buff_align, file_len);
logd("r_len:%d,in_len:%d\n",r_len,file_len);
//flush cache*
aicos_dcache_clean_range((unsigned long *)in_buff_align, (int64_t)in_len_align);
out_len = atoi(argv[3]);
if (out_len < file_len) {
loge("param error :%d\n",out_len);
ret = -1;
goto _exit;
}
// out buffer len align CACHE_LINE_SIZE
out_len_align = (out_len + CACHE_LINE_SIZE -1)/CACHE_LINE_SIZE*CACHE_LINE_SIZE;
out_buff = (unsigned long)aicos_malloc(MEM_CMA, out_len_align+(CACHE_LINE_SIZE -1));
if (out_buff == 0) {
loge("mpp_alloc fail\n");
ret = -1;
goto _exit;
}
//out buffer addr align CACHE_LINE_SIZE
out_buff_align = ((out_buff+CACHE_LINE_SIZE -1)&(~(CACHE_LINE_SIZE-1)));
// uncompressed
before = aic_get_time_us();
uncompress_len = mpp_zlib_uncompressed((unsigned char*)in_buff_align, file_len, (unsigned char*)out_buff_align, out_len_align);
after = aic_get_time_us();
logd("diff:%u\n",after-before);
if (uncompress_len < 0) {
loge("mpp_zlib_uncompressed fail\n");
ret = -1;
goto _exit;
}
//save uncompressed data
fd_out = open(argv[2], O_RDWR|O_CREAT);
if (fd_out < 0) {
loge("open %s fail\n",argv[2]);
ret = -1;
goto _exit;
}
// invalid cache
aicos_dcache_invalid_range((unsigned long *)out_buff_align, (int64_t)out_len_align);
w_len = write(fd_out,(void *)out_buff_align, uncompress_len);
logd("w_len:%d,uncompress_len:%d\n", w_len,uncompress_len);
close(fd_out);
_exit:
if(out_buff)
aicos_free(MEM_CMA, (void *)out_buff);
if(in_buff)
aicos_free(MEM_CMA, (void *)in_buff);
if(fd_in)
close(fd_in);
return ret;
}