【视频开发】【Live555】摄像头采集,264编码,live555直播
加入 摄像头采集和264编码,再使用live555直播
1、摄像头采集和264编码
将x264改成编码一帧的接口,码流不写入文件而是直接写入内存中(int Encode_frame 函数中)。
/** Filename: encodeapp.h* Auther: mlj* Create date: 2013/ 1/20*/ #ifndef _ENCODEAPP_H_ #define _ENCODEAPP_H_#include "x264.h" #include <stdint.h> #define WRITEOUT_RECONSTRUCTION 1typedef int32_t INT32; typedef signed char INT8;typedef struct _EncodeApp {x264_t *h;x264_picture_t pic;x264_param_t param;void *outBufs;//一帧码流的缓存int outBufslength;//总大小int bitslen;//实际码流大小 FILE *bits; // point to output bitstream file #ifdef WRITEOUT_RECONSTRUCTION FILE *p_rec ; #endif }EncodeApp; INT32 EncoderInit(EncodeApp* EncApp,INT8 *config_filename); INT32 EncoderEncodeFrame(EncodeApp* EncApp); INT32 EncoderDestroy(EncodeApp* EncApp);#endif
/** Filename: encodeapp.c* Auther: mlj* Create date: 2013/ 1/20*/ #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdio.h> #include "..\inc\encodeapp.h"#pragma comment(lib,"libx264.lib")extern int Encode_frame(EncodeApp* EncApp, x264_t *h, x264_picture_t *pic ); INT32 EncoderEncodeFrame(EncodeApp* EncApp) {//printf("processing frame %d...",j);int i;//int i_frame, i_frame_total;int64_t i_file=0;/* Encode frames *///EncApp->pic.i_pts = (int64_t)i_frame * (&EncApp->param)->i_fps_den; {/* Do not force any parameters */EncApp->pic.i_type = X264_TYPE_AUTO;EncApp->pic.i_qpplus1 = 0;}i_file += Encode_frame(EncApp, EncApp->h, &EncApp->pic );//fwrite(EncApp,EncApp->bits); #ifdef WRITEOUT_RECONSTRUCTION //write reconstruction #endifreturn 0; }INT32 EncoderDestroy(EncodeApp* EncApp) {x264_picture_clean( &EncApp->pic );x264_encoder_close( EncApp->h );if(EncApp->outBufs ) free(EncApp->outBufs ); fclose(EncApp->bits); #ifdef WRITEOUT_RECONSTRUCTION fclose(EncApp->p_rec); #endifreturn 0; }
//x264.c中改写 int Encode_frame(EncodeApp* EncApp, x264_t *h, x264_picture_t *pic ) {x264_picture_t pic_out;x264_nal_t *nal;int i_nal, i;int i_file = 0;if( x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) < 0 ){fprintf( stderr, "x264 [error]: x264_encoder_encode failed\n" );}EncApp->bitslen = 0;for( i = 0; i < i_nal; i++ ){int i_size;if( mux_buffer_size < nal[i].i_payload * 3/2 + 4 ){mux_buffer_size = nal[i].i_payload * 2 + 4;x264_free( mux_buffer );mux_buffer = x264_malloc( mux_buffer_size );}i_size = mux_buffer_size;x264_nal_encode( mux_buffer, &i_size, 1, &nal[i] );//i_file += p_write_nalu( EncApp->bits, mux_buffer, i_size );if( EncApp->outBufslength < ( EncApp->bitslen+i_size) ){void* temp= malloc( EncApp->bitslen+i_size);memcpy((unsigned char*)temp, (unsigned char*)(EncApp->outBufs), EncApp->bitslen);free(EncApp->outBufs);EncApp->outBufs = temp;}memcpy( (unsigned char*)(EncApp->outBufs)+ EncApp->bitslen,mux_buffer, i_size);EncApp->bitslen += i_size;}//p_write_nalu( EncApp->bits, (unsigned char*)EncApp->outBufs, EncApp->bitslen );//if (i_nal)// p_set_eop( EncApp->bits, &pic_out );return i_file; }INT32 EncoderInit(EncodeApp* EncApp,INT8 *config_filename) {int argc; cli_opt_t opt;static char *para[] ={"","-q","28","-o","test.264","G:\\sequence\\walk_vga.yuv","640x480","--no-asm"};char **argv = para;; //para[0] = argv[0];//argv = para;argc = sizeof(para)/sizeof(char*);x264_param_default( &EncApp->param );/* Parse command line */if( Parse( argc, argv, &EncApp->param, &opt ) < 0 )return -1; //param->i_frame_total = 100;// EncApp->param.i_width = 640;// EncApp->param.i_height = 480;//EncApp->param.rc.i_qp_constant = 28;if( ( EncApp->h = x264_encoder_open( &EncApp->param ) ) == NULL ){fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" );return -1;}/* Create a new pic */x264_picture_alloc( &EncApp->pic, X264_CSP_I420, EncApp->param.i_width, EncApp->param.i_height );EncApp->outBufs = malloc(1024*1024);EncApp->outBufslength = 1024*1024;EncApp->bits =0 ; #ifdef WRITEOUT_RECONSTRUCTION EncApp->p_rec = NULL; #endifEncApp->bits = fopen("test_vc.264","wb");#ifdef WRITEOUT_RECONSTRUCTION EncApp->p_rec = fopen("test_rec_vc.yuv", "wb"); #endifif(0==EncApp->bits){printf("Can't open output files!\n");return -1;}return 0; }
摄像头采集和264编码 源代码:http://download.csdn.NET/user/mlj318
结果速度不是很快,640x480 采集加编码只能达到10fps.
相关配置:需要OpenCV库和libx264.lib.
包含目录 G:\workspace\video4windows\CameraDS and 264\inc;H:\TDDOWNLOAD\OPEN_CV\opencv\build\include\opencv2;H:\TDDOWNLOAD\OPEN_CV\opencv\build\include\opencv;H:\TDDOWNLOAD\OPEN_CV\opencv\build\include;
库目录 G:\workspace\video4windows\CameraDS and code\lib;H:\TDDOWNLOAD\OPEN_CV\opencv\build\x86\vc10\lib;
链接器 附加库目录 G:\workspace\video4windows\CameraDS and 264\lib;
链接器 附加依赖项
opencv_calib3d243d.lib
opencv_contrib243d.lib
opencv_core243d.lib
opencv_features2d243d.lib
opencv_flann243d.lib
opencv_gpu243d.lib
opencv_haartraining_engined.lib
opencv_highgui243d.lib
opencv_imgproc243d.lib
opencv_legacy243d.lib
opencv_ml243d.lib
opencv_nonfree243d.lib
opencv_objdetect243d.lib
opencv_photo243d.lib
opencv_stitching243d.lib
opencv_ts243d.lib
opencv_video243d.lib
opencv_videostab243d.lib
libx264.lib
2、再加入live555直播
class Cameras { public:void Init();void GetNextFrame();void Destory(); public:CCameraDS camera1; CCameraDS camera2; EncodeApp encodeapp;IplImage *pFrame1 ;IplImage *pFrame2 ;unsigned char *RGB1;unsigned char *RGB2;unsigned char *YUV1;unsigned char *YUV2;unsigned char *YUV_merge; };void Cameras::Init() {// 1、考虑到已经存在了显示图像的窗口,那就不必再次驱动摄像头了,即便往下驱动那也是摄像头已被占用。if(IsWindowVisible(FindWindow(NULL, g_szTitle))){exit (-1);}//仅仅获取摄像头数目int m_iCamCount = CCameraDS::CameraCount();printf("There are %d cameras.\n", m_iCamCount);if(m_iCamCount==0){fprintf(stderr, "No cameras.\n");exit( -1); }//打开第一个摄像头if(! camera1.OpenCamera(0, false, WIDTH,HEIGHT)) //不弹出属性选择窗口,用代码制定图像宽和高 {fprintf(stderr, "Can not open camera1.\n");exit( -1); }if(! camera2.OpenCamera(1, false, WIDTH,HEIGHT)) //不弹出属性选择窗口,用代码制定图像宽和高 {fprintf(stderr, "Can not open camera2.\n");exit( -1); } cvNamedWindow("camera1");cvNamedWindow("camera2");EncoderInit(&encodeapp,NULL); pFrame1 = camera1.QueryFrame();pFrame2 = camera2.QueryFrame();RGB1=(unsigned char *)malloc(pFrame1->height*pFrame1->width*3);YUV1=(unsigned char *)malloc(pFrame1->height*pFrame1->width*1.5);RGB2=(unsigned char *)malloc(pFrame2->height*pFrame2->width*3);YUV2=(unsigned char *)malloc(pFrame2->height*pFrame2->width*1.5);YUV_merge=(unsigned char *)malloc(pFrame2->height*pFrame2->width*1.5); } void Cameras::GetNextFrame() {{pFrame1 = camera1.QueryFrame();pFrame2 = camera2.QueryFrame();cvShowImage("camera1", pFrame1);cvShowImage("camera2", pFrame2);for(int i=0;i<pFrame1->height;i++){for(int j=0;j<pFrame1->width;j++){RGB1[(i*pFrame1->width+j)*3] = pFrame1->imageData[i * pFrame1->widthStep + j * 3 + 2];;RGB1[(i*pFrame1->width+j)*3+1]= pFrame1->imageData[i * pFrame1->widthStep + j * 3 + 1];RGB1[(i*pFrame1->width+j)*3+2] = pFrame1->imageData[i * pFrame1->widthStep + j * 3 ]; RGB2[(i*pFrame1->width+j)*3] = pFrame2->imageData[i * pFrame1->widthStep + j * 3 + 2];;RGB2[(i*pFrame1->width+j)*3+1]= pFrame2->imageData[i * pFrame1->widthStep + j * 3 + 1];RGB2[(i*pFrame1->width+j)*3+2] = pFrame2->imageData[i * pFrame1->widthStep + j * 3 ]; }}Convert(RGB1, YUV1,pFrame1->width,pFrame1->height);Convert(RGB2, YUV2,pFrame2->width,pFrame2->height);mergeleftrigth(YUV_merge,YUV1,YUV2,pFrame2->width,pFrame2->height);unsigned char *p1,*p2;p1=YUV_merge;p2=encodeapp.pic.img.plane[0];// for(int i=0;i<pFrame1->height;i++){memcpy(p2,p1,pFrame1->width);p1+=pFrame1->width;p2+=WIDTH;}p2=encodeapp.pic.img.plane[1];for(int i=0;i<pFrame1->height/2;i++){memcpy(p2,p1,pFrame1->width/2);p1+=pFrame1->width/2;p2+=WIDTH/2;}p2=encodeapp.pic.img.plane[2];for(int i=0;i<pFrame1->height/2;i++){memcpy(p2,p1,pFrame1->width/2);p1+=pFrame1->width/2;p2+=WIDTH/2;}EncoderEncodeFrame(&encodeapp);} } void Cameras::Destory() {free(RGB1);free(RGB2);free(YUV1);free(YUV2);free(YUV_merge);camera1.CloseCamera();camera2.CloseCamera();cvDestroyWindow("camera1");cvDestroyWindow("camera2");EncoderDestroy(&encodeapp); }
void H264FramedLiveSource::doGetNextFrame() {//if( filesize(fp) > fMaxSize)// fFrameSize = fread(fTo,1,fMaxSize,fp); //else//{// fFrameSize = fread(fTo,1,filesize(fp),fp);// fseek(fp, 0, SEEK_SET);//}//fFrameSize = fMaxSize; TwoWayCamera.GetNextFrame();fFrameSize = TwoWayCamera.encodeapp.bitslen;if( fFrameSize > fMaxSize){fNumTruncatedBytes = fFrameSize - fMaxSize; fFrameSize = fMaxSize; } else{ fNumTruncatedBytes = 0; } memmove(fTo, TwoWayCamera.encodeapp.outBufs, fFrameSize); nextTask() = envir().taskScheduler().scheduleDelayedTask( 0,(TaskFunc*)FramedSource::afterGetting, this);//表示延迟0秒后再执行 afterGetting 函数return; }
源代码:http://download.csdn.net/user/mlj318
640x480 只能达到3.5fps.
相关配置:需要opencv库和libx264.lib.
包含目录 H:\TDDOWNLOAD\OPEN_CV\opencv\build\include\opencv2;H:\TDDOWNLOAD\OPEN_CV\opencv\build\include\opencv;H:\TDDOWNLOAD\OPEN_CV\opencv\build\include;G:\workspace\avs\live555test -send\live555test\inc;G:\workspace\avs\live555test\live555test\BasicUsageEnvironment\include;G:\workspace\avs\live555test\live555test\UsageEnvironment\include;G:\workspace\avs\live555test\live555test\liveMedia\include;G:\workspace\avs\live555test\live555test\groupsock\include;
库目录 G:\workspace\avs\live555test\live555test\lib;H:\TDDOWNLOAD\OPEN_CV\opencv\build\x86\vc10\lib;
链接器 附加库目录 G:\workspace\video4windows\CameraDS and 264\lib;
链接器 附加依赖项
opencv_calib3d243d.lib
opencv_contrib243d.lib
opencv_core243d.lib
opencv_features2d243d.lib
opencv_flann243d.lib
opencv_gpu243d.lib
opencv_haartraining_engined.lib
opencv_highgui243d.lib
opencv_imgproc243d.lib
opencv_legacy243d.lib
opencv_ml243d.lib
opencv_nonfree243d.lib
opencv_objdetect243d.lib
opencv_photo243d.lib
opencv_stitching243d.lib
opencv_ts243d.lib
opencv_video243d.lib
opencv_videostab243d.lib
libx264.lib
出现的错误:
1>LIBCMTD.lib(sprintf.obj) : error LNK2005: _sprintf 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义
1>LIBCMTD.lib(crt0dat.obj) : error LNK2005: _exit 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义
1>LIBCMTD.lib(crt0dat.obj) : error LNK2005: __exit 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义
LIBCMTD.lib与 MSVCRTD.lib 冲突,在链接器- 输入 -忽略特定默认库中加上 LIBCMTD.lib 即可。
FROM: http://www.cnblogs.com/mlj318/archive/2013/01/25/2873143.html
【视频开发】【Live555】摄像头采集,264编码,live555直播相关推荐
- 嵌入式监控【v4l2采集-vpu编码-live555推流】
嵌入式监控[v4l2采集->vpu编码->live555推流] 文章目录 嵌入式监控[v4l2采集->vpu编码->live555推流] 介绍 数据流图 一.v4l2 1.1 ...
- 【Android音视频开发】- 实时采集视频
前言 通过我的上一篇文章,可以知道直播大致有几个步骤:音视频采集 -> 美颜/滤镜/特效处理 -> 编码 -> 封包 -> 推流 -> 分发 -> 解码/渲染/播放 ...
- JavaCV音视频开发宝典:JavaCV实现mp3音频直播FM在线电台服务,无需流媒体服务,浏览器原生audio标签直接播放mp3,支持rtsp/rtmp/flv/hls/本地音视频源直接转码到mp3
<JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 之前写过使用JavaCV实现webm直播的文章: <JavaCV音视频 ...
- 【视频开发】RTSP SERVER(基于live555)详细设计
/* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...
- FPGA解码4line MIPI视频 IMX291/IMX290摄像头采集 提供工程源码和技术支持
目录 1.前言 2.Xilinx官方主推的MIPI解码方案 3.我已有的MIPI解码方案 4.纯Vhdl代码解码MIPI 5.vivado工程介绍 6.上板调试验证 7.福利:工程代码的获取 1.前言 ...
- H.264编码下直播视频添加水印的优化
2016年被称为"中国网络直播元年",网络直播已成为网络文化领域重要的经营模式和文化市场的重要组成部分.而以"直播造人"事件为节点,直播行业进入了严格规范化的时 ...
- 【尖端干货】H.264编码下直播视频添加水印的优化
2016年被称为"中国网络直播元年",网络直播已成为网络文化领域重要的经营模式和文化市场的重要组成部分.而以"直播造人"事件为节点,直播行业进入了严格规范化的时 ...
- OpenCV 笔记(03)— 读取视频、通过摄像头采集视频、采集视频 canny 边缘检测
我们本节学习如何利用 OpenCV 中的 VideoCapture 类,来对视频进行读取显示,以及调用摄像头. VideoCapture 它提供了从摄像机或视频文件捕获视频的 C++ 接口, 作用是从 ...
- JavaCV音视频开发宝典:实现Base64编码图片转换成图片文件通用转换器,以base64转png图片文件为例,其他图片格式也全部支持
<JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 在上一章中https://eguid.blog.csdn.net/artic ...
- Android 音视频入门之音频采集、编码、播放
今天我们学习音频的采集.编码.生成文件.转码等操作,我们生成三种格式的文件格式,pcm.wav.aac 三种格式,并且我们用 AudioStack 来播放音频,最后我们播放这个音频. 本篇文章你将学到 ...
最新文章
- 电脑基础操作_学打碟基础技术 - 数码打碟篇
- 矩阵的直接LU分解法
- 调整显示屏幕偏移和刷新频率[zt]
- Delphi XE 使用 MySQL 数据库一个奇怪的问题
- Qt Creator添加套件
- 还有什么不能做?——细谈在C#中读写Excel系列文章之一
- 亿佰特物联网dtu无线数传电台:新一代Lora无线模块通信技术
- Linux C 数据结构---链表(单向链表)
- 关于win10家庭版不能开启虚拟机的问题
- php使用switch语句编写程序,PHP控制语句之“switch”语句实例详解
- 电脑文件一键实时备份同步至云端(百度云盘)
- 在线web魔方和在线AI象棋
- AI魔幻行为大赏:细数机器视觉的9大应用场景
- hive Cannot truncate non-managed table
- 视频教程-网络安全与渗透测试工程师-渗透测试
- linux 黑屏后死机,如何修复各种各样的黑屏死机
- 陶朗集团任命新总裁兼CEO;开利完成对广东积微集团的收购;宁德时代获大众集团电芯测试实验室认证 | 能动...
- 学生查分系统该怎么制作?
- 传输层协议之TCP协议详解
- 拷贝构造函数的三种使用情况
热门文章
- M1卡读写软件C#源代码
- 广联达软件未检测到加密锁请重新插入加密锁或网络服务器
- java pdf 阅读器_纯Java文档阅读器(word、pdf等)
- ILSpy .NET反编译工具下载地址
- 解决:macOS下logisim左侧侧边栏被隐藏
- ArcView,ArcGis,MapObjects,ISRI有什么区别
- 测试开始系列——功能测试用例模板
- qt高级编程附源码_c++ gui qt4编程附源码
- 用matlab还原全息图像,一种全息再现图像的零级像消除方法与流程
- 基于大数据的图书推荐系统