【媒体流】libx264 将rgb24格式转换为h264
来源:互联网 发布:淘宝宝贝经常修改价格 编辑:程序博客网 时间:2024/06/07 05:34
简介
最近我在将自己的久笔记本放在家里做小型的远程监控,在网络传输视频时需要用到h264码流。然而我对h264只能说知道只知道它是一个视频编码格式,仅此而已。然后某度一下之后发现有开源的库可以直接使用。libx264就这样被我发现了。在其他博客中混迹了一段时间后发现,网上基本上是没有说使用libx264 将rgb24 数据格式转 h264的。基本上都是讲yuv420转的,说什么libx264只支持yuv420格式作为输入源,在这个我不想吐槽太多了。这篇博文主要是讲述如会将摄像头捕获回来的个图像数据转换为h264码流并保存到本地。然后可以用vlc查看。
当时我是看雷神的这篇博客踏入这神圣的殿堂的
雷霄骅 基于libx264(编码YUV为H.264)
本文框架
- opencv 采集图像
- libx264编码
- vlc效果演示
opencv 采集图像
opencv 相信很多博友都应该知道。现在都可以说是烂大街了。现在我就直接使用它来作为我们采集图像的工具(可能有点大材小用了)。
// bolgLibx264.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <opencv/cv.h>#include <opencv/highgui.h>using namespace std;using namespace cv;#define WIDTH 640#define HEIGHT 480void testVideoCapture(void){ VideoCapture cap(0); Mat frame; if (cap.isOpened() == false) cout << "can't not capture an usb camera from your computer!!!" << endl; while (true) { cap >> frame; if (frame.empty()) continue; resize(frame, frame, Size(WIDTH, HEIGHT)); imshow("frame", frame); waitKey(1); }}int _tmain(int argc, _TCHAR* argv[]){ testVideoCapture(); return 0;}
这里给出的代码片段只是简单的使用opencv 采集pc机中默认摄像头并显示图像,代码中的resize是缩放函数,我这里是将图像分辨率规定为640*480了。下面的是上边代码片段的运行效果:
libx264编码
在上面的采集的基础上添加编码程序,至于怎么添加libx264 可以参考【雷霄骅博客】在简介中我已经给出了。我这里就不废话了。直接上代码。
// bolgLibx264.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <opencv/cv.h>#include <opencv/highgui.h>#if defined ( __cplusplus)extern "C"{#include <stdint.h>#include "x264.h"};#else#include "x264.h"#endifusing namespace std;using namespace cv;#define WIDTH 640#define HEIGHT 480#define VENC_FPS 30typedef struct __X264_ENCODER__{ x264_t* m_pX264Handle; x264_param_t* m_pX264Param; x264_picture_t* m_pX264Pic_out; x264_picture_t* m_pX264Pic_in; x264_nal_t* m_pX264Nals; int m_x264iNal; FILE *m_x264Fp;}X264Encoder;void initX264Encoder(X264Encoder &x264Encoder,char *filePath){ x264Encoder.m_x264Fp = fopen(filePath, "wb"); x264Encoder.m_pX264Param = (x264_param_t *)malloc(sizeof(x264_param_t)); assert(x264Encoder.m_pX264Param); x264_param_default(x264Encoder.m_pX264Param); x264_param_default_preset(x264Encoder.m_pX264Param, "veryfast", "zerolatency"); x264_param_apply_profile(x264Encoder.m_pX264Param, "baseline"); x264Encoder.m_pX264Param->i_threads = X264_THREADS_AUTO;//X264_SYNC_LOOKAHEAD_AUTO; // 取空缓冲区继续使用不死锁的保证 // 视频选项 x264Encoder.m_pX264Param->i_width = WIDTH; // 要编码的图像宽度. x264Encoder.m_pX264Param->i_height = HEIGHT; // 要编码的图像高度 // 帧率 x264Encoder.m_pX264Param->b_vfr_input = 0;//0时只使用fps控制帧率 int m_frameRate = VENC_FPS; x264Encoder.m_pX264Param->i_fps_num = m_frameRate; // 帧率分子 x264Encoder.m_pX264Param->i_fps_den = 1; // 帧率分母 x264Encoder.m_pX264Param->i_timebase_den = x264Encoder.m_pX264Param->i_fps_num; x264Encoder.m_pX264Param->i_timebase_num = x264Encoder.m_pX264Param->i_fps_den; x264Encoder.m_pX264Param->b_intra_refresh = 0; x264Encoder.m_pX264Param->b_annexb = 1; //m_pX264Param->b_repeat_headers = 0; x264Encoder.m_pX264Param->i_keyint_max = m_frameRate; x264Encoder.m_pX264Param->i_csp = X264_CSP_BGR;//X264_CSP_I420;// x264Encoder.m_pX264Param->i_log_level = X264_LOG_INFO;//X264_LOG_DEBUG; x264Encoder.m_x264iNal = 0; x264Encoder.m_pX264Nals = NULL; x264Encoder.m_pX264Pic_in = (x264_picture_t *)malloc(sizeof(x264_picture_t)); if (x264Encoder.m_pX264Pic_in == NULL) exit(1); else memset(x264Encoder.m_pX264Pic_in, 0, sizeof(x264_picture_t)); //x264_picture_alloc(m_pX264Pic_in, X264_CSP_I420, m_pX264Param->i_width, m_pX264Param->i_height); x264_picture_alloc(x264Encoder.m_pX264Pic_in, X264_CSP_BGR, x264Encoder.m_pX264Param->i_width, x264Encoder.m_pX264Param->i_height); x264Encoder.m_pX264Pic_in->i_type = X264_TYPE_AUTO; x264Encoder.m_pX264Pic_out = (x264_picture_t *)malloc(sizeof(x264_picture_t)); if (x264Encoder.m_pX264Pic_out == NULL) exit(1); else memset(x264Encoder.m_pX264Pic_out, 0, sizeof(x264_picture_t)); x264_picture_init(x264Encoder.m_pX264Pic_out); x264Encoder.m_pX264Handle = x264_encoder_open(x264Encoder.m_pX264Param); assert(x264Encoder.m_pX264Handle);}void convertFrameToX264Img(x264_image_t *x264InImg,Mat &frame){ //RGB方式 int srcSize = frame.rows*frame.cols; x264InImg->plane[0] = frame.data; x264InImg->plane[1] = frame.data + srcSize; x264InImg->plane[2] = frame.data + srcSize;}void encoderImg(X264Encoder &x264Encoder,Mat &frame){ //转换图像格式 convertFrameToX264Img(&x264Encoder.m_pX264Pic_in->img,frame); x264Encoder.m_pX264Pic_in->i_pts++; int ret = x264_encoder_encode(x264Encoder.m_pX264Handle, &x264Encoder.m_pX264Nals, &x264Encoder.m_x264iNal, x264Encoder.m_pX264Pic_in, x264Encoder.m_pX264Pic_out); if (ret< 0){ printf("Error.\n"); return; } for (int i = 0; i < x264Encoder.m_x264iNal; ++i) { fwrite(x264Encoder.m_pX264Nals[i].p_payload, 1, x264Encoder.m_pX264Nals[i].i_payload, x264Encoder.m_x264Fp); }}void testVideoEncoder(void){ X264Encoder x264Encoder; initX264Encoder(x264Encoder,"myCamera.h264"); VideoCapture cap(0); Mat frame; if (cap.isOpened() == false) cout << "can't not capture an usb camera from your computer!!!" << endl; while (true) { cap >> frame; if (frame.empty()) continue; resize(frame, frame, Size(WIDTH, HEIGHT)); encoderImg(x264Encoder, frame); imshow("frame", frame); waitKey(30); }}int _tmain(int argc, _TCHAR* argv[]){ testVideoEncoder(); return 0;}
vlc演示
将代码产生的myCamera.h264 用vlc播放器打开即可播放
注:整个工程稍后上传至csdn下载中心。没有积分的可以留言联系我给你直接发过去。
源码下载链接
阅读全文
1 0
- 【媒体流】libx264 将rgb24格式转换为h264
- YV12 格式的图片转换为 RGB24 格式
- linux 下将rgb24转化为rgb565的格式
- 媒体流格式转换
- YUV2格式转换成RGB24格式解析
- YUV2格式转换成RGB24格式解析
- 图像转换:RGB24转换为YUV420P
- YUV420格式转换为H264 2D格式
- YUV422格式的数据转换成RGB24
- YUV格式学习:YUV444转换RGB24
- YUV格式学习:Y转换成RGB24
- linux下使用ffmpeg将flv、mp4、rmvb转换为libx264的mp4
- 将 BDF 格式转换为 PCF 格式
- 将ppt格式转换为pdf格式
- h264编码前必须要转换为yuv420p格式
- ios libx264 h264 encode
- FFmpeg转换yuv为h264视频流
- 将FAT卷转换为NTFS格式
- bzoj 1101: [POI2007]Zap
- 表单struts2上传 不可缺少属性
- codeforces 485D (RMQ)
- Javascript与java相同的3des加密(使用etdesede/CBC/PKCS5Padding )
- java获取当前tomcat进程(linux)
- 【媒体流】libx264 将rgb24格式转换为h264
- CodeForces 571B Minimization(dp)
- 算法训练 特殊的数字四十
- 算法的时间复杂度和空间复杂度-总结
- 微信公众平台开发入门教程
- 如何在eclipse中开发flume
- Hibernate 5.2版本以前的Criteria查询
- 怎么配置提高mysql
- mysql学习记录