在用libx264做h264压缩的时候,我们可以通过命令ffmpeg -h encoder=libx264来查看它所支持的输入格式

Encoder libx264 [libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10]:

General capabilities: delay threads

Threading capabilities: auto

Supported pixel formats: yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p nv12 nv16 nv21

yuv422p不是YUY2, 可以看见我从USB摄像头直接取出的数据YUY2是不能直接当作输入格式的。(采集YUY2数据查看上一篇文章https://my.oschina.net/noevilme/blog/4462358)

常有3种方案来做转换:

自己按像素点做转换

使用libyuv

使用ffmpeg swscale

我推荐第2种和第3种, 大佬们的算法都有优化的,除非你觉得自己更牛X。据江湖传言libyuv是swscale的几倍速度,我没测过哈。

转换前先了解一下YUY2和I420数据格式,话说YUV各种名称实在有点乱,参考http://fourcc.org/yuv.php

YUY2, YUYV, YUV422  这三个都是YUY2的别称,ffmpeg定义AV_PIX_FMT_YUYV422。

Y U Y V Y U Y V

Y U Y V Y U Y V

Y U Y V Y U Y V

Y U Y V Y U Y V

Y U Y V Y U Y V

Y U Y V Y U Y V

Y U Y V Y U Y V

I420, IYUV, YUV420P, YU12, 前面这几个都是I420的名字,其中YUV420P又是几个格式的统称,特定环境下就是I420,ffmpeg定义AV_PIX_FMT_YUV420P。

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

U U U U U U U U

V V V V V V V V

一、使用libyuv::YUY2ToI420

// Convert YUY2 to I420.

LIBYUV_API

int YUY2ToI420(const uint8_t* src_yuy2,

int src_stride_yuy2,

uint8_t* dst_y,

int dst_stride_y,

uint8_t* dst_u,

int dst_stride_u,

uint8_t* dst_v,

int dst_stride_v,

int width,

int height);

上面是接口定义,stride参数是指图片格式行距。

int libyuv_convert(const char *input_file, const char *output_file, int width,

int height) {

FILE *in_fp = fopen(input_file, "rb");

if (!in_fp) {

std::cout << "open input failure" << std::endl;

return 1;

}

FILE *out_fp = fopen(output_file, "wb");

if (!out_fp) {

std::cout << "open output failure" << std::endl;

return 1;

}

uint8_t *yuy2_image = new uint8_t[width * height * 2];

uint8_t *i420_image = new uint8_t[width * height * 3 / 2];

while (fread(yuy2_image, 1, width * height * 2, in_fp) ==

(size_t)width * height * 2) {

uint8_t *i420_y = i420_image;

uint8_t *i420_u = i420_y + width * height;

uint8_t *i420_v = i420_u + width * height / 4;

libyuv::YUY2ToI420(yuy2_image, width * 2, i420_y, width, i420_u,

width / 2, i420_v, width / 2, width, height);

fwrite(i420_image, 1, width * height * 3 / 2, out_fp);

}

delete[] i420_image;

delete[] yuy2_image;

fclose(in_fp);

fclose(out_fp);

return 0;

}

二、使用sws_scale

swscale库是ffmpeg的一部分,所以在操作的时候用AVFrame结构更加方便,不然得自己定义一个二维数组。

int ffmpeg_convert2(const char *input_file, const char *output_file, int width,

int height) {

SwsContext *context;

FILE *in_fp, *out_fp;

in_fp = fopen(input_file, "rb");

if (!in_fp) {

std::cout << "open input failure" << std::endl;

return 1;

}

out_fp = fopen(output_file, "wb");

if (!out_fp) {

std::cout << "open out file failure" << std::endl;

fclose(in_fp);

return 1;

}

context = sws_getContext(width, height, AV_PIX_FMT_YUYV422, width, height,

AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr,

nullptr, nullptr);

AVFrame *av_frame_in = av_frame_alloc();

auto yuy2_image_size =

av_image_alloc(av_frame_in->data, av_frame_in->linesize, width, height,

AV_PIX_FMT_YUYV422, 1);

AVFrame *av_frame_out = av_frame_alloc();

auto i420_image_size =

av_image_alloc(av_frame_out->data, av_frame_out->linesize, width,

height, AV_PIX_FMT_YUV420P, 1);

while (fread(av_frame_in->data[0], 1, yuy2_image_size, in_fp) ==

(size_t)yuy2_image_size) {

sws_scale(context, av_frame_in->data, av_frame_in->linesize, 0, height,

av_frame_out->data, av_frame_out->linesize);

fwrite(av_frame_out->data[0], 1, i420_image_size, out_fp);

}

sws_freeContext(context);

av_freep(&av_frame_in->data[0]);

av_freep(&av_frame_out->data[0]);

av_frame_free(&av_frame_in);

av_frame_free(&av_frame_out);

fclose(in_fp);

fclose(out_fp);

return 0;

}

调用函数

#include

#include

#include

#include

#include

#include

extern "C" {

#include

#include

#include

#include

#include

};

int main(int argc, char **argv) {

const char *input_file =

"1280x720_yuy2.yuv";

const char *output_file = "yuv_1280x720_i420.yuv";

libyuv_convert(input_file, output_file, 1280, 720);

ffmpeg_convert2(input_file, "ff_1280x720_i420.yuv", 1280, 720);

return 0;

}

linux mp4转h264工具,Linux音视频开发之二:转换YUY2到I420便于压缩成h264相关推荐

  1. 迅为RK3399开发板音视频开发之Debian9 多媒体测试

    iTOP3399平台 Debian 系统音视频部分应用层软件采用的是 Gstreamer,支持硬件编解码.本节所有的 示例均是基于 Gstreamer 命令行的形式. iTOP3399 平台内部有一个 ...

  2. Android音视频开发之,全网疯传

    int audioFormat, int bufferSizeInBytes, int mode, int sessionId) * streamType,Android手机上提供音频管理策略,按下音 ...

  3. WebRTC 音视频开发之路

    早在2014年就通过WebRTC实现了PC客户端的实时视频语音,那时P2P连接的建立使用的WebRTC自带的libjingle库,使用peerconnection的API实现的.后来在做远程桌面,文件 ...

  4. AVI音视频封装格式学习(四)——linux系统C语言AVI格式音视频封装应用

    拖了很久的AVI音视频封装实例,花了一天时间终于调完了,兼容性不是太好,但作为参考学习使用应该没有问题.RIFF和AVI以及WAV格式,可以参考前面的一些文章.这里详细介绍将一个H264视频流和一个2 ...

  5. FFmpeg 工具:音视频开发都用它,快@你兄弟来看丨音视频工具

    (本文基本逻辑:ffmpeg 常用命令介绍 → ffplay 常用命令介绍 → ffprobe 常用命令介绍) 从事音视频开发的程序员几乎都应该知道或使用过 FFmpeg.FFmpeg 是一个开源软件 ...

  6. 适用于linux的解压工具,Linux系统中常用的压缩和解压缩工具

    Linux系统中常用的压缩和解压缩工具 压缩:以时间换空间的一种操作: 压缩的原理:标记和替换: 压缩比:压缩之前与压缩之后的文件大小的比值:其中:纯文本文件的压缩比较大,视频.图像等文件压缩比小 能 ...

  7. mac上使用FFmpeg工具处理音视频

    上一篇我们了解了什么是 m3u8 文件,这一节我们了解一下,怎样通过 ffmpeg工具 去下载视频文件. ffmpeg ffmpeg 是强大的媒体文件转换工具,常用于转码,可选命令非常多,编码器.视频 ...

  8. linux批量部署war工具,Linux 批量一键部署工具 Expect

    Linux 批量一键部署工具 Expect 既然没有遇到过,做好准备总是好的.这是自己送给自己的话,现在运维做自动话越来越多,自己就学以下,记录笔记.目前主流的有puppet.Expect.pssh等 ...

  9. linux bes二进制查看工具,Linux的命令及工具

    1.查看系统运行的进程 # ps auxw 2.netstat命令 查看系统监听的服务 # netstat -ln -a所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连 ...

最新文章

  1. C#事件的发送方和接收方(订阅方)
  2. python写小程序-用python写个简单的小程序,编译成exe跑在win10上
  3. 战胜 Flash ,HTML5 还需要什么?
  4. iframe js 加载失败_如何提高Vue项目首页的加载速度
  5. MFC窗口颜色的设置
  6. Webpack不生成index.html
  7. Hibernate处理MySQL的时间
  8. WebbUpload的验证问题
  9. HDU4405(期望DP)
  10. 中国银保监会公布银行业金融机构目前共有4608家(附全部名录)
  11. pythonsqlite3模糊_让 Python 更加充分的使用 Sqlite3
  12. Elementary OS 使用fcitx安装搜狗词库、搜狗输入法(Ubuntu通用)
  13. 多人同时用一个linux主机,云服务器能否多人使用?
  14. 如何计算近似纳什均衡_博弈 | 精炼贝叶斯纳什均衡
  15. 不要把别人对你的好,当作是理所当然
  16. VIJOS-P1626 桐桐的糖果计划
  17. 蛋糕瓜分殆尽 谁会成为下一个手游造富的加速器?
  18. 美国主机BlueHost vs HostEase
  19. 昆虫繁殖《信息学奥赛一本通-递推算法》
  20. CSS字体的连写方式

热门文章

  1. android手动触发ke,手机重启问题快速分析定位指南
  2. 手把手做一个JSP入门程序(九):购物车的基本实现(Servlet)
  3. 杂交水稻 CET4/6
  4. Machine Learning---PNN
  5. 基于html+js实现轮播图(自动轮播、左右按钮、小圆点点击及切换图片)
  6. 基于ssm+vue的班级同学录网站管理系统 elementui
  7. php unlink权限设置,php中删除文件用unlink函数权限判断
  8. 主动学习(Active Learning) 概述、策略和不确定性度量
  9. 如何组织编程教育培训
  10. python_split()函数使用方法