加入 摄像头采集和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 1 typedef 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
#endif
return 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);
#endif
return 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;
#endif
EncApp->bits = fopen("test_vc.264","wb"); #ifdef WRITEOUT_RECONSTRUCTION
EncApp->p_rec = fopen("test_rec_vc.yuv", "wb");
#endif if(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直播的更多相关文章

  1. 【视频开发】RTSP SERVER(基于live555)详细设计

    /* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...

  2. ffmpeg摄像头采集h264编码RTP发送

    一. 相关API说明 1. av_register_all 2. avformat_network_init 不管是流媒体发送还是流媒体接收, 需要先执行该函数. 3. avformat_alloc_ ...

  3. Android IOS WebRTC 音视频开发总结(七六)-- 探讨直播低延迟低流量的粉丝连麦技术

    本文主要探讨基于WebRTC的P2P直播粉丝连麦技术 (作者:郝飞,亲加云CTO,编辑:dora),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注微信公众号blacker(微信ID:blac ...

  4. WebRTC 音视频开发

    WebRTC 音视频开发 webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...

  5. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  6. (转)C++实现RTMP协议发送H.264编码及AAC编码的音视频,摄像头直播

    转:http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RT ...

  7. 【秒懂音视频开发】23_H.264编码

    本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...

  8. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  9. C++实现RTMP协议发送H.264编码及AAC编码的音视频

    http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RTMP ...

随机推荐

  1. 《BUG创造队》第三次作业:团队项目原型设计与开发

    项目 内容 这个作业属于哪个课程 2016级软件工程 这个作业的要求在哪里 实验六 团队作业3:团队项目原型设计与开发 团队名称 BUG创造队 作业学习目标 ①掌握软件原型开发技术:②学会使用软件原型 ...

  2. 项目Beta冲刺(团队)-凡事预则立

    所属课程 软件工程1916|W(福州大学) 作业要求 项目Beta冲刺(团队)-凡事预则立 团队名称 基于云的胜利冲锋队 作业目标 为 Beta 冲刺规划安排 1.讨论组长是否重选的议题和结论 由于我 ...

  3. wordpress调用指定post type文章怎么操作

    我们有时会用wordpress创建好几种post type文章,比如默认的post文章和product文章,如果我们要在每个页面的底部调用post type类型为post最新文章要如何操作呢?那我们就 ...

  4. STM32L4R9使用HAL库调试IIC注意事项

    STM32使用Cubemx生成的代码中,用到IIC的驱动,但是始终不能读写,因此使用逻辑分析仪,发现原本地址为0x58的写成了0x20,因此肯定是地址错了.因此,总结如下: 1.需要逻辑分析仪分析II ...

  5. Codeforces1114C Trailing Loves (or L'oeufs?)

    链接:http://codeforces.com/problemset/problem/1114/C 题意:给定数字$n$和$b$,问$n!$在$b$进制下有多少后导零. 寒假好像写过这道题当时好像完 ...

  6. Tensorflow细节-P312-PROJECTOR

    首先进行数据预处理,需要生成.tsv..jpg文件 import matplotlib.pyplot as plt import numpy as np import os from tensorfl ...

  7. Linux 系统管理——文件系统与LVM、磁盘配额实例

    1.为主机增加80G SCSI 接口硬盘 2.划分三个各20G的主分区 3.将三个主分区转换为物理卷(pvcreate),扫描系统中的物理卷 4.使用两个物理卷创建卷组,名字为myvg,查看卷组大小 ...

  8. 关于html异步加载外部json文件报错问题

    一. HTML代码如下: 参考网站(echarts-JSON请求数据):https://blog.csdn.net/you23hai45/article/details/51585506 <!D ...

  9. C++2.0新特性(八)——<Smart Pointer(智能指针)之unique_ptr>

    一.概念介绍 unique_ptr它是一种在异常发生时可帮助避免资源泄露的smart pointer,实现了独占式拥有的概念,意味着它可确保一个对象和其他相应资源在同一时间只被一个pointer拥有, ...

  10. spark集成kerberos

    1.生成票据 1.1.创建认证用户 登陆到kdc服务器,使用root或者可以使用root权限的普通用户操作: # kadmin.local -q “addprinc -randkey spark/yj ...