• libyuv 再次封装打包与测试


           

    目录

    一、接口函数

    二、编译封装

    三、测试

    四、参考文献


            上篇文章中进行了libyuv在HI3516平台上的编译和测试。libyuv所处理的数据类型一般都是NV21 YUV420格式。需求端客户要对8位的灰度图像进行放缩处理,同时对外发布版本的时候不能直接告诉客户我们用的是libyuv,所以需要对libyuv进行一次函数接口重新封装,打包成一个我们自己的库对外发布。

    一、接口函数

            函数目的是对把输入的Y8数据转换成I420送入yuvlib,同时将放缩后的result中的y8抠出来,送出,代码如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include "libyuv.h"
    7. #include "y8_resize.h"
    8. enum ColorFormat {
    9. YUV_I420 = 0,
    10. YUV_NV21,
    11. YUV_NV12,
    12. BGR ,
    13. RGB ,
    14. BGRA,
    15. RGBA,
    16. ABGR,
    17. ARGB,
    18. };
    19. struct Buffer {
    20. uint32_t width, height;
    21. uint8_t *data[3];
    22. uint32_t stride[3];
    23. ColorFormat color;
    24. };
    25. typedef enum FilterMode {
    26. kFilterNone = 0, // Point sample; Fastest. 640*480--3.67
    27. kFilterLinear = 1, // Filter horizontally only.
    28. kFilterBilinear = 2, // Faster than box, but lower quality scaling down.
    29. kFilterBox = 3 // Highest quality.
    30. } FilterModeEnum;
    31. void LibyuvResize_I420(const Buffer *src, Buffer *dst, int mode)
    32. {
    33. // you should make complete info of buffer src, stride data width height
    34. dst->stride[0] = dst->width; //stride for y
    35. dst->stride[1] = dst->width >> 1; //stride for u
    36. dst->stride[2] = dst->width >> 1; //stride for v
    37. uint32_t dst_y_size = dst->width * dst->height;
    38. uint32_t dst_u_size = dst->stride[1] * (dst->height >> 1);
    39. //uint32_t dst_v_size = dst->stride[2] * (dst->height >> 1);
    40. dst->data[1] = dst->data[0] + dst_y_size;
    41. dst->data[2] = dst->data[1] + dst_u_size;
    42. dst->color = ColorFormat::YUV_I420;
    43. if(mode==0)
    44. {
    45. libyuv::I420Scale(src->data[0], src->stride[0],
    46. src->data[1], src->stride[1],
    47. src->data[2], src->stride[2],
    48. src->width, src->height,
    49. dst->data[0], dst->stride[0],
    50. dst->data[1],dst->stride[1],
    51. dst->data[2],dst->stride[2],
    52. dst->width, dst->height,
    53. libyuv::FilterMode::kFilterNone);//
    54. }else if(mode==1)
    55. {
    56. libyuv::I420Scale(src->data[0], src->stride[0],
    57. src->data[1], src->stride[1],
    58. src->data[2], src->stride[2],
    59. src->width, src->height,
    60. dst->data[0], dst->stride[0],
    61. dst->data[1],dst->stride[1],
    62. dst->data[2],dst->stride[2],
    63. dst->width, dst->height,
    64. libyuv::FilterMode::kFilterLinear);//
    65. }else if(mode==2)
    66. {
    67. libyuv::I420Scale(src->data[0], src->stride[0],
    68. src->data[1], src->stride[1],
    69. src->data[2], src->stride[2],
    70. src->width, src->height,
    71. dst->data[0], dst->stride[0],
    72. dst->data[1],dst->stride[1],
    73. dst->data[2],dst->stride[2],
    74. dst->width, dst->height,
    75. libyuv::FilterMode::kFilterBilinear);//
    76. }else if(mode == 3)
    77. {
    78. libyuv::I420Scale(src->data[0], src->stride[0],
    79. src->data[1], src->stride[1],
    80. src->data[2], src->stride[2],
    81. src->width, src->height,
    82. dst->data[0], dst->stride[0],
    83. dst->data[1],dst->stride[1],
    84. dst->data[2],dst->stride[2],
    85. dst->width, dst->height,
    86. libyuv::FilterMode::kFilterBox);//
    87. }else{
    88. printf("Mode error \n");
    89. }
    90. }
    91. int guide_y8_resize(unsigned char *srcImg,
    92. int width, int height,
    93. unsigned char *dstImg, float scale, int mode)
    94. {
    95. int i,j,k;
    96. int len = width*height;
    97. int len_i420 = width*height + width*height/2;//yyyy u v
    98. int width_scale = scale * width;
    99. int height_scale = scale * height;
    100. int len_scale = width_scale*height_scale;
    101. unsigned char *image_uv=(unsigned char*)malloc(len/2*sizeof(unsigned char));
    102. unsigned char *result_uv = (unsigned char*)malloc(len_scale/2*sizeof(unsigned char));
    103. struct Buffer srcBuf, dstBuf;
    104. srcBuf.color = YUV_I420;
    105. srcBuf.width = width;
    106. srcBuf.height = height;
    107. srcBuf.stride[0] = width;
    108. srcBuf.stride[1] = width >> 1;
    109. srcBuf.stride[2] = width >> 1;
    110. uint32_t src_y_size = len;
    111. uint32_t src_u_size = srcBuf.stride[1] * (srcBuf.height >> 1);
    112. srcBuf.data[0] = srcImg;//image_y8;
    113. srcBuf.data[1] = image_uv;//srcBuf.data[0] + src_y_size;
    114. srcBuf.data[2] = srcBuf.data[1] + src_u_size;
    115. dstBuf.width = width_scale;
    116. dstBuf.height = height_scale;
    117. uint32_t dst_u_size = width_scale / 2 * height_scale / 2;
    118. dstBuf.data[0] = dstImg;//result_y8;
    119. dstBuf.data[1] = result_uv;
    120. dstBuf.data[2] = dstBuf.data[1] + dst_u_size;
    121. LibyuvResize_I420(&srcBuf, &dstBuf, mode);
    122. free(image_uv);
    123. free(result_uv);
    124. return 1;
    125. }

    二、编译封装

    这里分别把编译动态库和静态库的makefile贴出来

    1. #########################################
    2. ############ make xx.so
    3. #########################################
    4. CHIP = arm-himix200-linux-
    5. #CHIP = arm-linux-gnueabihf-
    6. #CHIP = arm-fsl-linux-gnueabi-
    7. CC = $(CHIP)gcc
    8. CXX= $(CHIP)g++
    9. objects = y8_resize.o libyuv.a
    10. CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
    11. CFLAGS += -fPIC -shared
    12. CFLAGS += -std=c++11 -Wno-narrowing
    13. TOPDIR=.
    14. CFLAGS += -I$(TOPDIR)/include
    15. .PHONY:all
    16. all:libImage.so
    17. libImage.so: $(objects)
    18. @echo ------------linking...
    19. $(CC) $(CFLAGS) -o $@ $^ -lc -lpthread -ldl
    20. @echo ------------ libImage.so over !!!
    21. .c.o:
    22. @echo ------------gcc .c
    23. $(CC) $(CFLAGS) -c $^
    24. .cpp.o:
    25. @echo ------------g++ .cpp
    26. $(CXX) $(CFLAGS) -c -fPIC $^
    27. clean:
    28. rm -f libImage.so *.o; pwd;
    1. ###############################
    2. ############### make xx.a
    3. ################################
    4. CHIP = arm-himix200-linux-
    5. #CHIP = arm-linux-gnueabihf-
    6. #CHIP = arm-fsl-linux-gnueabi-
    7. CC = $(CHIP)gcc
    8. CXX= $(CHIP)g++
    9. AR = $(CHIP)ar
    10. AS = $(CHIP)as
    11. objects = y8_resize.o libyuv.a
    12. CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
    13. CFLAGS += -fPIC -shared
    14. CFLAGS += -std=c++11 -Wno-narrowing
    15. TOPDIR=.
    16. CFLAGS += -I$(TOPDIR)/include
    17. .PHONY:all
    18. all: libImage.a
    19. libImage.a: $(objects)
    20. @echo ------------linking...
    21. # $(AR) -o $@ $^ -lc -lpthread -ldl
    22. $(AR) -crv libyuv.a y8_resize.o
    23. @echo ------------libImage.a over !!!
    24. .c.o:
    25. @echo ------------gcc .c
    26. $(CC) $(CFLAGS) -c $^
    27. .cpp.o:
    28. @echo ------------g++ .cpp
    29. $(CXX) $(CFLAGS) -c -fPIC $^
    30. clean:
    31. rm -f libImage.a *.o; pwd;

            这里需要说明的是,$(AR)  -crv libyuv.a y8_resize.o 是把y8_resize.o打包到了libyuv.a中,此时的libyuv.a已经不再是原始的libyuv库中编译出来的libyuv.a。

    三、测试

            测试代码如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include "time.h"
    7. #include "bmp.h"
    8. #include
    9. #include "y8_resize.h"
    10. int main(void)
    11. {
    12. int i,j,k;
    13. int width = 384;//256;//384;
    14. int height = 288;//192;//288;
    15. int len = width*height;
    16. int len_i420 = width*height + width*height/2;//yyyy u v
    17. float time_use=0;
    18. struct timeval start_time;
    19. struct timeval end_time;
    20. struct timeval temp_time;
    21. FILE* fp = fopen("../../../../append_file/car_384288.yuv", "rb");
    22. // FILE* fp = fopen("../../../append_file/256_192.raw", "rb");//y16
    23. if (!fp)
    24. return -1;
    25. unsigned char *image_y8=(unsigned char*)malloc(len*3/2*sizeof(unsigned char));
    26. unsigned char *image_rgb888=(unsigned char*)malloc(len*3*sizeof(unsigned char));
    27. // unsigned char *image_i420=(unsigned char*)malloc(len_i420*sizeof(unsigned char));
    28. float scale = 1.5;
    29. int width_scale = scale * width;
    30. int height_scale = scale * height;
    31. int len_scale = width_scale*height_scale;
    32. unsigned char *result_y8 = (unsigned char*)malloc(len_scale*3/2*sizeof(unsigned char));
    33. unsigned char *result_rgb888 = (unsigned char*)malloc(len_scale*3*sizeof(unsigned char));
    34. fread(image_y8, 1, len, fp);
    35. for(i=0;i
    36. {
    37. for(j=0;j
    38. {
    39. image_rgb888[i*3*width + j*3] = image_y8[i*width+j];
    40. image_rgb888[i*3*width + j*3 + 1] = image_y8[i*width+j];
    41. image_rgb888[i*3*width + j*3 + 2] = image_y8[i*width+j];
    42. }
    43. }
    44. bmp_creator("123.bmp", image_rgb888, height, width);
    45. for(k=0;k<5;k++)
    46. {
    47. gettimeofday(&start_time,NULL);
    48. guide_y8_resize(image_y8, width, height, result_y8, scale, k);
    49. gettimeofday(&end_time,NULL);
    50. time_use = (end_time.tv_sec-start_time.tv_sec)*1000000 + (end_time.tv_usec-start_time.tv_usec);//us
    51. printf("---- guide_y8_resize mode %d cost %8.2f ms \n", k, time_use/1000);
    52. }
    53. for(i=0;i
    54. {
    55. for(j=0;j
    56. {
    57. result_rgb888[i*3*width_scale + j*3] = result_y8[i*width_scale+j];
    58. result_rgb888[i*3*width_scale + j*3 + 1] = result_y8[i*width_scale+j];
    59. result_rgb888[i*3*width_scale + j*3 + 2] = result_y8[i*width_scale+j];
    60. }
    61. }
    62. bmp_creator("234.bmp", result_rgb888, height_scale, width_scale);
    63. fclose(fp);
    64. free(image_y8);
    65. free(image_rgb888);
    66. free(result_y8);
    67. free(result_rgb888);
    68. return 1;
    69. }

    app的makefile

    1. objects = test.o bmp.o
    2. CFLAGS = -O3 -mfpu=neon -mthumb -march=armv7-a -funsafe-math-optimizations -mfloat-abi=softfp
    3. CFLAGS += -std=c++11 -Wno-narrowing
    4. TOPDIR=.
    5. CFLAGS += -I$(TOPDIR)/include
    6. .PHONY:all
    7. all:demo
    8. demo: $(objects)
    9. @echo ------------linking...
    10. # arm-himix200-linux-g++ $(CFLAGS) -o $@ $^ -lc -lgomp -lpthread -ldl -L./ -lImage
    11. arm-himix200-linux-g++ $(CFLAGS) -o $@ $^ -lc -lgomp -lpthread -ldl -L./ -lyuv
    12. @echo ------------over !!!
    13. # cp demo ./bin; mv *.o ./bin
    14. .c.o:
    15. @echo ------------gcc .c
    16. arm-himix200-linux-gcc $(CFLAGS) -c $^
    17. .cpp.o:
    18. @echo ------------g++ .cpp
    19. arm-himix200-linux-g++ $(CFLAGS) -c $^
    20. clean:
    21. rm -f demo *.o; pwd;

    测试结果:(测试前请删除前面生成的libImage.so以便验证静态库的有效性)

    1. /mnt/alg_test/libyuv/diy_lib_test/test_lib # ./demo
    2. ---- guide_y8_resize mode 0 cost 3.75 ms
    3. ---- guide_y8_resize mode 1 cost 4.78 ms
    4. ---- guide_y8_resize mode 2 cost 9.17 ms
    5. ---- guide_y8_resize mode 3 cost 9.13 ms
    6. Mode error
    7. ---- guide_y8_resize mode 4 cost 0.06 ms

    四、参考文献

    Linux 静态库 编译和使用

    C++静态库与动态库

  • 相关阅读:
    (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