目录
上篇文章中进行了libyuv在HI3516平台上的编译和测试。libyuv所处理的数据类型一般都是NV21 YUV420格式。需求端客户要对8位的灰度图像进行放缩处理,同时对外发布版本的时候不能直接告诉客户我们用的是libyuv,所以需要对libyuv进行一次函数接口重新封装,打包成一个我们自己的库对外发布。
函数目的是对把输入的Y8数据转换成I420送入yuvlib,同时将放缩后的result中的y8抠出来,送出,代码如下:
- #include
- #include
- #include
- #include
- #include
- #include "libyuv.h"
- #include "y8_resize.h"
-
- enum ColorFormat {
- YUV_I420 = 0,
- YUV_NV21,
- YUV_NV12,
- BGR ,
- RGB ,
- BGRA,
- RGBA,
- ABGR,
- ARGB,
- };
-
-
- struct Buffer {
- uint32_t width, height;
- uint8_t *data[3];
- uint32_t stride[3];
- ColorFormat color;
- };
-
- typedef enum FilterMode {
- kFilterNone = 0, // Point sample; Fastest. 640*480--3.67
- kFilterLinear = 1, // Filter horizontally only.
- kFilterBilinear = 2, // Faster than box, but lower quality scaling down.
- kFilterBox = 3 // Highest quality.
- } FilterModeEnum;
-
-
- void LibyuvResize_I420(const Buffer *src, Buffer *dst, int mode)
- {
- // you should make complete info of buffer src, stride data width height
- dst->stride[0] = dst->width; //stride for y
- dst->stride[1] = dst->width >> 1; //stride for u
- dst->stride[2] = dst->width >> 1; //stride for v
- uint32_t dst_y_size = dst->width * dst->height;
- uint32_t dst_u_size = dst->stride[1] * (dst->height >> 1);
- //uint32_t dst_v_size = dst->stride[2] * (dst->height >> 1);
- dst->data[1] = dst->data[0] + dst_y_size;
- dst->data[2] = dst->data[1] + dst_u_size;
- dst->color = ColorFormat::YUV_I420;
-
- if(mode==0)
- {
- libyuv::I420Scale(src->data[0], src->stride[0],
- src->data[1], src->stride[1],
- src->data[2], src->stride[2],
- src->width, src->height,
- dst->data[0], dst->stride[0],
- dst->data[1],dst->stride[1],
- dst->data[2],dst->stride[2],
- dst->width, dst->height,
- libyuv::FilterMode::kFilterNone);//
- }else if(mode==1)
- {
- libyuv::I420Scale(src->data[0], src->stride[0],
- src->data[1], src->stride[1],
- src->data[2], src->stride[2],
- src->width, src->height,
- dst->data[0], dst->stride[0],
- dst->data[1],dst->stride[1],
- dst->data[2],dst->stride[2],
- dst->width, dst->height,
- libyuv::FilterMode::kFilterLinear);//
- }else if(mode==2)
- {
- libyuv::I420Scale(src->data[0], src->stride[0],
- src->data[1], src->stride[1],
- src->data[2], src->stride[2],
- src->width, src->height,
- dst->data[0], dst->stride[0],
- dst->data[1],dst->stride[1],
- dst->data[2],dst->stride[2],
- dst->width, dst->height,
- libyuv::FilterMode::kFilterBilinear);//
- }else if(mode == 3)
- {
- libyuv::I420Scale(src->data[0], src->stride[0],
- src->data[1], src->stride[1],
- src->data[2], src->stride[2],
- src->width, src->height,
- dst->data[0], dst->stride[0],
- dst->data[1],dst->stride[1],
- dst->data[2],dst->stride[2],
- dst->width, dst->height,
- libyuv::FilterMode::kFilterBox);//
- }else{
- printf("Mode error \n");
- }
-
- }
-
-
- int guide_y8_resize(unsigned char *srcImg,
- int width, int height,
- unsigned char *dstImg, float scale, int mode)
- {
- int i,j,k;
- int len = width*height;
- int len_i420 = width*height + width*height/2;//yyyy u v
- int width_scale = scale * width;
- int height_scale = scale * height;
- int len_scale = width_scale*height_scale;
-
- unsigned char *image_uv=(unsigned char*)malloc(len/2*sizeof(unsigned char));
- unsigned char *result_uv = (unsigned char*)malloc(len_scale/2*sizeof(unsigned char));
-
- struct Buffer srcBuf, dstBuf;
- srcBuf.color = YUV_I420;
- srcBuf.width = width;
- srcBuf.height = height;
- srcBuf.stride[0] = width;
- srcBuf.stride[1] = width >> 1;
- srcBuf.stride[2] = width >> 1;
- uint32_t src_y_size = len;
- uint32_t src_u_size = srcBuf.stride[1] * (srcBuf.height >> 1);
- srcBuf.data[0] = srcImg;//image_y8;
- srcBuf.data[1] = image_uv;//srcBuf.data[0] + src_y_size;
- srcBuf.data[2] = srcBuf.data[1] + src_u_size;
-
- dstBuf.width = width_scale;
- dstBuf.height = height_scale;
- uint32_t dst_u_size = width_scale / 2 * height_scale / 2;
- dstBuf.data[0] = dstImg;//result_y8;
- dstBuf.data[1] = result_uv;
- dstBuf.data[2] = dstBuf.data[1] + dst_u_size;
-
- LibyuvResize_I420(&srcBuf, &dstBuf, mode);
-
- free(image_uv);
- free(result_uv);
-
- return 1;
- }
这里分别把编译动态库和静态库的makefile贴出来
- #########################################
- ############ make xx.so
- #########################################
-
- CHIP = arm-himix200-linux-
- #CHIP = arm-linux-gnueabihf-
- #CHIP = arm-fsl-linux-gnueabi-
-
- CC = $(CHIP)gcc
- CXX= $(CHIP)g++
-
- objects = y8_resize.o libyuv.a
-
- CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
- CFLAGS += -fPIC -shared
- CFLAGS += -std=c++11 -Wno-narrowing
-
- TOPDIR=.
- CFLAGS += -I$(TOPDIR)/include
- .PHONY:all
-
-
- all:libImage.so
-
- libImage.so: $(objects)
- @echo ------------linking...
- $(CC) $(CFLAGS) -o $@ $^ -lc -lpthread -ldl
- @echo ------------ libImage.so over !!!
-
- .c.o:
- @echo ------------gcc .c
- $(CC) $(CFLAGS) -c $^
-
- .cpp.o:
- @echo ------------g++ .cpp
- $(CXX) $(CFLAGS) -c -fPIC $^
-
- clean:
- rm -f libImage.so *.o; pwd;
- ###############################
- ############### make xx.a
- ################################
-
- CHIP = arm-himix200-linux-
- #CHIP = arm-linux-gnueabihf-
- #CHIP = arm-fsl-linux-gnueabi-
-
- CC = $(CHIP)gcc
- CXX= $(CHIP)g++
- AR = $(CHIP)ar
- AS = $(CHIP)as
-
- objects = y8_resize.o libyuv.a
-
- CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
- CFLAGS += -fPIC -shared
- CFLAGS += -std=c++11 -Wno-narrowing
-
- TOPDIR=.
- CFLAGS += -I$(TOPDIR)/include
- .PHONY:all
-
- all: libImage.a
-
- libImage.a: $(objects)
- @echo ------------linking...
- # $(AR) -o $@ $^ -lc -lpthread -ldl
- $(AR) -crv libyuv.a y8_resize.o
- @echo ------------libImage.a over !!!
-
- .c.o:
- @echo ------------gcc .c
- $(CC) $(CFLAGS) -c $^
-
- .cpp.o:
- @echo ------------g++ .cpp
- $(CXX) $(CFLAGS) -c -fPIC $^
-
- clean:
- rm -f libImage.a *.o; pwd;
这里需要说明的是,$(AR) -crv libyuv.a y8_resize.o 是把y8_resize.o打包到了libyuv.a中,此时的libyuv.a已经不再是原始的libyuv库中编译出来的libyuv.a。
测试代码如下:
- #include
- #include
- #include
- #include
- #include
- #include "time.h"
- #include "bmp.h"
- #include
- #include "y8_resize.h"
-
- int main(void)
- {
- int i,j,k;
- int width = 384;//256;//384;
- int height = 288;//192;//288;
- int len = width*height;
- int len_i420 = width*height + width*height/2;//yyyy u v
-
- float time_use=0;
- struct timeval start_time;
- struct timeval end_time;
- struct timeval temp_time;
-
- FILE* fp = fopen("../../../../append_file/car_384288.yuv", "rb");
- // FILE* fp = fopen("../../../append_file/256_192.raw", "rb");//y16
- if (!fp)
- return -1;
-
- unsigned char *image_y8=(unsigned char*)malloc(len*3/2*sizeof(unsigned char));
- unsigned char *image_rgb888=(unsigned char*)malloc(len*3*sizeof(unsigned char));
- // unsigned char *image_i420=(unsigned char*)malloc(len_i420*sizeof(unsigned char));
-
- float scale = 1.5;
- int width_scale = scale * width;
- int height_scale = scale * height;
- int len_scale = width_scale*height_scale;
- unsigned char *result_y8 = (unsigned char*)malloc(len_scale*3/2*sizeof(unsigned char));
- unsigned char *result_rgb888 = (unsigned char*)malloc(len_scale*3*sizeof(unsigned char));
-
- fread(image_y8, 1, len, fp);
-
- for(i=0;i
- {
- for(j=0;j
- {
- image_rgb888[i*3*width + j*3] = image_y8[i*width+j];
- image_rgb888[i*3*width + j*3 + 1] = image_y8[i*width+j];
- image_rgb888[i*3*width + j*3 + 2] = image_y8[i*width+j];
- }
- }
-
- bmp_creator("123.bmp", image_rgb888, height, width);
-
- for(k=0;k<5;k++)
- {
- gettimeofday(&start_time,NULL);
- guide_y8_resize(image_y8, width, height, result_y8, scale, k);
- gettimeofday(&end_time,NULL);
- time_use = (end_time.tv_sec-start_time.tv_sec)*1000000 + (end_time.tv_usec-start_time.tv_usec);//us
- printf("---- guide_y8_resize mode %d cost %8.2f ms \n", k, time_use/1000);
- }
-
- for(i=0;i
- {
- for(j=0;j
- {
- result_rgb888[i*3*width_scale + j*3] = result_y8[i*width_scale+j];
- result_rgb888[i*3*width_scale + j*3 + 1] = result_y8[i*width_scale+j];
- result_rgb888[i*3*width_scale + j*3 + 2] = result_y8[i*width_scale+j];
- }
- }
-
- bmp_creator("234.bmp", result_rgb888, height_scale, width_scale);
-
- fclose(fp);
- free(image_y8);
- free(image_rgb888);
- free(result_y8);
- free(result_rgb888);
-
- return 1;
- }
app的makefile
- objects = test.o bmp.o
- CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
- CFLAGS += -std=c++11 -Wno-narrowing
- TOPDIR=.
- CFLAGS += -I$(TOPDIR)/include
- .PHONY:all
-
- all:demo
-
- demo: $(objects)
- @echo ------------linking...
- # arm-himix200-linux-g++ $(CFLAGS) -o $@ $^ -lc -lgomp -lpthread -ldl -L./ -lImage
- arm-himix200-linux-g++ $(CFLAGS) -o $@ $^ -lc -lgomp -lpthread -ldl -L./ -lyuv
- @echo ------------over !!!
- # cp demo ./bin; mv *.o ./bin
-
- .c.o:
- @echo ------------gcc .c
- arm-himix200-linux-gcc $(CFLAGS) -c $^
-
- .cpp.o:
- @echo ------------g++ .cpp
- arm-himix200-linux-g++ $(CFLAGS) -c $^
-
- clean:
- rm -f demo *.o; pwd;
测试结果:(测试前请删除前面生成的libImage.so以便验证静态库的有效性)
- /mnt/alg_test/libyuv/diy_lib_test/test_lib # ./demo
- ---- guide_y8_resize mode 0 cost 3.75 ms
- ---- guide_y8_resize mode 1 cost 4.78 ms
- ---- guide_y8_resize mode 2 cost 9.17 ms
- ---- guide_y8_resize mode 3 cost 9.13 ms
- Mode error
- ---- guide_y8_resize mode 4 cost 0.06 ms
四、参考文献
-
相关阅读:
(echarts)折线图封装相关总结及使用
敏捷开发模型:一种灵活、协作和持续的软件开发方法
C++开发面试之——C++11新特性20问
jsp美食管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
Flink SQL --Flink 整合 hive
三季度都快过完了,看看项目经理年初立的flag怎样了?
超简单的视频截取方法,迅速提取所需片段!
gici-open示例数据运行(1.1开阔环境数据运行)
h52206前端面试题汇总(89题)
通过js来实现一元二次方程的效果,输入a,b,c系数后可计算出x1和x2的值
-
原文地址:https://blog.csdn.net/fuhanga123/article/details/126137423