文档章节

YUYV422转YUV420

宇文成欣
 宇文成欣
发布于 2016/12/07 17:46
字数 481
阅读 66
收藏 1

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

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/time.h>

uint32_t width = 1280;
uint32_t height = 720;

uint32_t getcurrenttime()
{
  struct timeval t;
  gettimeofday(&t, NULL);
  return (uint32_t)(t.tv_sec * 1000 + t.tv_usec / 1000);
}

int convert(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
{
  uint8_t *y = NULL;
  uint8_t *u = NULL;
  uint8_t *v = NULL;
  y = outbuf;
  u = y + 1280 * 720;
  v = u + 1280 * 720 / 2;

  uint32_t i = 0;
  uint8_t swith = 0;
  while (i < buflen) {
    if (swith == 0 || swith == 2) {
      *y++ = inbuf[i];
      swith++;
    } else if (swith == 1) {
      *u++ = inbuf[i];
      swith++;
    } else if (swith == 3) {
      *v++ = inbuf[i];
      swith = 0;
    }
    i++;
  }
  return 0;
}

void yuyv2yuv420(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
{
  uint8_t *y = NULL;
  uint8_t *u = NULL;
  uint8_t *v = NULL;
  int u_c = 0;
  int v_c = 0;
  y = outbuf;
  u = y + 1280 * 720;
  v = u + 1280 * 720 / 4;
  bool swith = true;
  uint32_t i = 0, j = 0;

  for (i = 0; i < buflen; i += 2) {
    *y++ = inbuf[i];
  }
  
  for (i = 0; i < height; i += 2) {
    for (j = 1; j < width << 1; j += 2) {
      if (swith) {
        *u++ = ((uint8_t *)(inbuf + (i * (width << 1))))[j];
        swith = false;
        u_c++;
      } else {
        *v++ = ((uint8_t *)(inbuf + (i * (width << 1))))[j];
        swith = true;
        v_c++;
      }
    }
  }
}

int main()
{
  int ret = 0;
  uint32_t inframesize = width * height * 2; 
  uint32_t outframesize = width * height * 3 / 2;
  printf("inframesize: %u\n", inframesize);
  printf("outframesize: %u\n", outframesize);
  printf("size: %u\n", width * height / 4);
  FILE *infb = NULL;
  FILE *outfb = NULL;
  uint8_t *inbuf = NULL;
  uint8_t *outbuf = NULL; 
  
  inbuf = (uint8_t *)malloc(sizeof(uint8_t) * inframesize);
  if (inbuf == NULL) {
    printf("malloc inbuf failed\n");
    ret = -1;
    goto Error;
  }
  outbuf = (uint8_t *)malloc(sizeof(uint8_t) * outframesize);
  if (outbuf == NULL) {
    printf("malloc outbuf failed\n");
    ret = -1;
    goto Error;
  }

  infb = fopen("./test.yuv", "rb");
  if (infb == NULL) {
    printf("open ./test.yuv failed\n");
    ret = -1;
    goto Error;
  }
  outfb = fopen("./test.yuv420", "wb");
  if (outfb == NULL) {
    printf("open ./test.yuv422 failed\n");
    ret = -1;
    goto Error;
  }

  uint32_t start;
  uint32_t end;
  while (fread(inbuf, 1, inframesize, infb) == inframesize) {
    //convert(inbuf, inframesize, outbuf);
    start = getcurrenttime();
    yuyv2yuv420(inbuf, inframesize, outbuf);
    end = getcurrenttime();
    printf("%d\n", end - start);
    fwrite(outbuf, 1, outframesize, outfb);
  }

Error:
  if (inbuf != NULL) free(inbuf);
  if (outbuf != NULL) free(outbuf);
  if (infb != NULL) fclose(infb);
  if (outfb != NULL) fclose(outfb);
  return ret;
}

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

 

 

 

© 著作权归作者所有

共有 人打赏支持
上一篇: 嘿嘿
下一篇: 黑暗料理之香蕉
宇文成欣
粉丝 1
博文 3
码字总数 623
作品 0
绵阳
程序员
私信 提问
一款开源的 Android YUV 格式查看工具

1. YUVDroidTools 最近项目比较忙,好久没有写文章了,也没有为开源社区贡献点啥了,这个周末抽空整理了一下自己一直维护的一份基于 ffmpeg 的 YUV 格式转换代码,写了一个简单的 Android YU...

Jhuster
2016/06/25
0
0
一个简单的 YUV 播放器--YUVPlayer

工程说明 VS2010 MFC工程,源码有部分参考Yuvviewer代码,界面参考YUV Player Deluxe风格。 参数设置界面: 关于界面: 功能 可播放各种格式的YUV文件。 默认预留常见分辨率,同时支持自定义...

latelee
2017/03/29
417
1
Android MediaCodec图片合成视频

利用MediaCodec可以录制视频,可是可以将图片合成视频吗?之前使用ffmpeg来实现。但是,ffmpeg却是c++写的,而且非常占用内存,虽然它是非常棒的音视频处理库,但是杀鸡焉用牛刀,所以今天就...

陨石坠灭
2018/12/11
0
0
YUV420如何扣取指定区域的图像数据

YUV420数据的存储方式有两类:planar和packed。planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。对于packed的YUV格式,每个像素点的Y,U,V是连续交...

Gobert
2014/12/04
0
0
YUV420如何扣取指定区域的图像数据

YUV420数据的存储方式有两类:planar和packed。planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。对于packed的YUV格式,每个像素点的Y,U,V是连续交...

IcedBeer
2016/11/03
86
0

没有更多内容

加载失败,请刷新页面

加载更多

JavaScript继承(二)——借用构造函数

JavaScript继承(一)——原型链中提出原型链继承的两个问题:一是原型的数据共享问题,二是创建子类型的实例时,不能向父类型的构造函数中传递参数。这两个问题的根源还是在于使用原型模式创...

Bob2100
31分钟前
0
0
day25:比较两个文件内容|杀进程|并发备份数据库|并发进程备份mysql库|监控全国CDN网站节点|

1、有两个文件 a.txt 和 b.txt,把 a.txt 中有的但 b.txt 中没有的行找出来,并写入列 c.txt,然后计算 c 的行数; 注释:比较两个文件两个文件不同,可以用的方法:diff md5sum grep -vf $1 $...

芬野de博客
47分钟前
4
0
抓包工具Charles

背景介绍 Charles是一款很实用,界面很友好(至少跟fiddler比起来),功能强大的抓包神器,因为它是基于 java 开发的,所以跨平台,Mac、Linux、Windows下都是可以使用的,并且在Android和i...

Jack088
48分钟前
2
0
徒手撸一个简单的RPC框架

徒手撸一个简单的RPC框架 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的服务就像调用本地方法一样,其中用到的知识有序列化和反序列化、动态...

不学无数的程序员
今天
2
0
Java 面试题目最全集合1000+ 大放送,能答对70%就去BATJTMD试试~

2019,相对往年我们会发现今年猎头电话少了,大部分企业年终奖缩水,加薪幅度也不如往年,选择好offer就要趁早,现在开始准备吧,刷一波Java面试题,能回答70%就去BATJTMD大胆试试~ 以下是2...

mikechen优知
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部