Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14895
  • 博文数量: 3
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 32
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-20 18:59
文章分类
文章存档

2016年(1)

2015年(1)

2014年(1)

我的朋友

分类: C/C++

2016-12-07 17:58:34

这几天做一个音视频采集与传输的项目,用v4l2来采集视频数据,公司给的USB摄像头只支持packed yuyv422数据,需要将其转换为planar yuv420,折腾了一下,将代码贴出来,说不定有同学可以用到。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6. #include <sys/time.h>

  7. uint32_t width = 1280;
  8. uint32_t height = 720;

  9. uint32_t getcurrenttime()
  10. {
  11.   struct timeval t;
  12.   gettimeofday(&t, NULL);
  13.   return (uint32_t)(t.tv_sec * 1000 + t.tv_usec / 1000);
  14. }

  15. int convert(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
  16. {
  17.   uint8_t *y = NULL;
  18.   uint8_t *u = NULL;
  19.   uint8_t *v = NULL;
  20.   y = outbuf;
  21.   u = y + 1280 * 720;
  22.   v = u + 1280 * 720 / 2;

  23.   uint32_t i = 0;
  24.   uint8_t swith = 0;
  25.   while (i < buflen) {
  26.     if (swith == 0 || swith == 2) {
  27.       *y++ = inbuf[i];
  28.       swith++;
  29.     } else if (swith == 1) {
  30.       *u++ = inbuf[i];
  31.       swith++;
  32.     } else if (swith == 3) {
  33.       *v++ = inbuf[i];
  34.       swith = 0;
  35.     }
  36.     i++;
  37.   }
  38.   return 0;
  39. }

  40. void yuyv2yuv420(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
  41. {
  42.   uint8_t *y = NULL;
  43.   uint8_t *u = NULL;
  44.   uint8_t *v = NULL;
  45.   int u_c = 0;
  46.   int v_c = 0;
  47.   y = outbuf;
  48.   u = y + 1280 * 720;
  49.   v = u + 1280 * 720 / 4;
  50.   bool swith = true;
  51.   uint32_t i = 0, j = 0;

  52.   for (i = 0; i < buflen; i += 2) {
  53.     *y++ = inbuf[i];
  54.   }
  55.   
  56.   for (i = 0; i < height; i += 2) {
  57.     for (j = 1; j < width << 1; j += 2) {
  58.       if (swith) {
  59.         *u++ = ((uint8_t *)(inbuf + (i * width << 1)))[j];
  60.         swith = false;
  61.         u_c++;
  62.       } else {
  63.         *v++ = ((uint8_t *)(inbuf + (i * width << 1)))[j];
  64.         swith = true;
  65.         v_c++;
  66.       }
  67.     }
  68.   }
  69. }

  70. int main()
  71. {
  72.   int ret = 0;
  73.   uint32_t inframesize = width * height * 2;
  74.   uint32_t outframesize = width * height * 3 / 2;
  75.   printf("inframesize: %u\n", inframesize);
  76.   printf("outframesize: %u\n", outframesize);
  77.   printf("size: %u\n", width * height / 4);
  78.   FILE *infb = NULL;
  79.   FILE *outfb = NULL;
  80.   uint8_t *inbuf = NULL;
  81.   uint8_t *outbuf = NULL;
  82.   
  83.   inbuf = (uint8_t *)malloc(sizeof(uint8_t) * inframesize);
  84.   if (inbuf == NULL) {
  85.     printf("malloc inbuf failed\n");
  86.     ret = -1;
  87.     goto Error;
  88.   }
  89.   outbuf = (uint8_t *)malloc(sizeof(uint8_t) * outframesize);
  90.   if (outbuf == NULL) {
  91.     printf("malloc outbuf failed\n");
  92.     ret = -1;
  93.     goto Error;
  94.   }

  95.   infb = fopen("./test.yuv", "rb");
  96.   if (infb == NULL) {
  97.     printf("open ./test.yuv failed\n");
  98.     ret = -1;
  99.     goto Error;
  100.   }
  101.   outfb = fopen("./test.yuv420", "wb");
  102.   if (outfb == NULL) {
  103.     printf("open ./test.yuv422 failed\n");
  104.     ret = -1;
  105.     goto Error;
  106.   }

  107.   uint32_t start;
  108.   uint32_t end;
  109.   while (fread(inbuf, 1, inframesize, infb) == inframesize) {
  110.     //convert(inbuf, inframesize, outbuf);
  111.     start = getcurrenttime();
  112.     yuyv2yuv420(inbuf, inframesize, outbuf);
  113.     end = getcurrenttime();
  114.     printf("%d\n", end - start);
  115.     fwrite(outbuf, 1, outframesize, outfb);
  116.   }

  117. Error:
  118.   if (inbuf != NULL) free(inbuf);
  119.   if (outbuf != NULL) free(outbuf);
  120.   if (infb != NULL) fclose(infb);
  121.   if (outfb != NULL) fclose(outfb);
  122.   return ret;
  123. }

代码中的convert函数,只是将packed yuyv422转换成planar。


阅读(2497) | 评论(0) | 转发(0) |
0

上一篇:Alsa中PCM参数设置

下一篇:没有了

给主人留下些什么吧!~~