文档章节

YUYV422转YUV420

宇文成欣
 宇文成欣
发布于 2016/12/07 17:46
字数 481
阅读 61
收藏 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
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
图文详解YUV420数据格式

完整的链接: http://www.xuebuyuan.com/1541892.html YUV格式有两大类:planar和packed。 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。...

aspirs
2016/01/24
63
0

没有更多内容

加载失败,请刷新页面

加载更多

centos7安装rsync及两台机器进行文件同步

centos7安装rsync及两台机器进行文件同步 2017年12月21日 11:17:46 码农下的天桥 阅读数:2210 标签: centosrsync同步 更多 个人分类: 后端 所属专栏: 研发模式及运维 版权声明:本文为博...

linjin200
7分钟前
0
0
jpg、jpeg、png... 的区别

jpg、jpeg、png... 的区别 对于做设计这一行的人来说,这几个图片格式是最常用的,也是最常见的,几乎每一天都要与他们打交道。 刚刚入门的新人通常不知道在什么地方如何使用他们或者说如何更...

DemonsI
26分钟前
2
0
白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明。而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等。今天,...

oKong
31分钟前
1
0
Character的static方法

基本类型char的包装类是Character,使用的比较多,大家是比较熟悉的。 我只是觉得里面有很多static方法,平时不怎么用,学习一下怎么实现的,或许日后就用到了。 static int compare(char x,...

woshixin
43分钟前
1
0
正则介绍_sed

10月17日任务 9.4/9.5 sed sed工具 匹配打印 -n 只打印匹配行,不然其他行也会打印出来 p 打印(配合-n使用) [root@centos7 tmp]# sed -n '/root/'p passwd root:x:0:0:root:/root:/bin/ba...

robertt15
43分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部