加入 摄像头采集和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. 《基于B_S模式的教务管理系统设计与实现》论文笔记(十九)

    标题:广州医科大学考务管理系统的研究与分析 一.基本信息 时间:2012 来源:南通大学杏林学院 关键词:: 考务管理:网络考试:数据库系统 二.研究内容 1.重修补考报名考务管理系统采用的技术: 重 ...

  2. oracle 将与本端(name)联系的人取出

    本人与其他所有人认识的SQL: 首先新建测试表 create table DIM_IA_TEST6 ( NAME ), OTHERNAME ) ) 插入数据 --如果没有重复的记录,则不用去重使用un ...

  3. Java 第12次作业--你的生日

    题目:计算自己的出生日期距今天多少天,再将自己的出生日期利用SimpleDateFormat类设定的格式输出显示. 代码: import java.util.*; import java.text.* ...

  4. B-树,B+树,B*树总结

    链接地址:https://blog.csdn.net/v_JULY_v/article/details/6530142 B+树 B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+ ...

  5. Windows10安装Redis过程

    下载 Redis下载地址:https://github.com/microsoftarchive/redis/releases 以3.2.100版本为例,下载Redis-x64-3.2.100.zip ...

  6. AtCoder Beginner Contest 125 解题报告

    那天晚上刚好有事就咕了. 最近的那一场E题还不会写.F题全场又只过了三个?留坑吧... A - Biscuit Generator #include <cstdio> using name ...

  7. SQL Server 中PAGELATCH_x和PAGEIOLATCH_x解析

    0.参考文献 Microsoft SQL Server企业级平台管理实践 第11章 Buffer Latch Timeout的解析 什么是PAGELATCH和PAGEIOLATCH 1.PAGELAT ...

  8. CollectionUtils.select用法

    import java.util.ArrayList;import java.util.List; import org.apache.commons.collections.CollectionUt ...

  9. edgedb-js 来自官方的js 驱动

    目前对于edgedb 主要还是来自官方的python驱动,目前js 版本的已经快发布了,代码在github 可以看到了 同时官方文档也提供了一个关于edgedb 内部的协议说明,结合js 驱动以及文档 ...

  10. Redis BGSAVE因为内存不足 fork 失败导致目标 Redis 无法访问的问题

    中秋的时候正在外面愉快的在外卖喝着咖啡玩电脑......突发 redis 报警从 sentry 应用端曝出的错误 MISCONF Redis is configured to save RDB sna ...