直接上代码

// demo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
extern "C"
{
#include "../../common/common.h"
#include "../../common/cpu.h""
#include "../../x264.h"
#include "../../encoder/set.h"
}
#include "librtmp/rtmp_sys.h"
#include "librtmp/log.h"
#include "librtmp/amf.h"
#include "CameraDS.h"
void ConvertYCbCr2BGR(unsigned char *pYUV,unsigned char *pBGR,int iWidth,int iHeight);
void ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned char *yuv);
int InitSockets()
{
#ifdef WIN32
    WORD version;
    WSADATA wsaData;
    version = MAKEWORD(1, 1);
    return (WSAStartup(version, &wsaData) == 0);
#else
    return TRUE;
#endif
}
inline void CleanupSockets()
{
#ifdef WIN32
    WSACleanup();
#endif
}
#define HEX2BIN(a)      (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
int hex2bin(char *str, char **hex)
{
    char *ptr;
    int i, l = strlen(str);
    if (l & 1)
        return 0;
    *hex = (char *)malloc(l/2);
    ptr = *hex;
    if (!ptr)
        return 0;
    for (i=0; i
        *ptr++ = (HEX2BIN(str[i]) << 4) | HEX2BIN(str[i+1]);
    return l/2;
}
char * put_byte( char *output, uint8_t nVal )
{
    output[0] = nVal;
    return output+1;
}
char * put_be16(char *output, uint16_t nVal )
{
    output[1] = nVal & 0xff;
    output[0] = nVal >> 8;
    return output+2;
}
char * put_be24(char *output,uint32_t nVal )
{
    output[2] = nVal & 0xff;
    output[1] = nVal >> 8;
    output[0] = nVal >> 16;
    return output+3;
}
char * put_be32(char *output, uint32_t nVal )
{
    output[3] = nVal & 0xff;
    output[2] = nVal >> 8;
    output[1] = nVal >> 16;
    output[0] = nVal >> 24;
    return output+4;
}
char *  put_be64( char *output, uint64_t nVal )
{
    output=put_be32( output, nVal >> 32 );
    output=put_be32( output, nVal );
    return output;
}
char * put_amf_string( char *c, const char *str )
{
    uint16_t len = strlen( str );
    c=put_be16( c, len );
    memcpy(c,str,len);
    return c+len;
}
char * put_amf_double( char *c, double d )
{
    *c++ = AMF_NUMBER;    
    {
        unsigned char *ci, *co;
        ci = (unsigned char *)&d;
        co = (unsigned char *)c;
        co[0] = ci[7];
        co[1] = ci[6];
        co[2] = ci[5];
        co[3] = ci[4];
        co[4] = ci[3];
        co[5] = ci[2];
        co[6] = ci[1];
        co[7] = ci[0];
    }
    return c+8;
}
int main(int argc, char * argv[])
{
    if (argc<2)
    {
        RTMP_LogPrintf("RTMP_URL IS NULL!!!/n");
        //return -1;
    }
    if (!InitSockets())
    {
        RTMP_LogPrintf("InitSockets Error!/n");
        return -1;
    }
    RTMP_LogPrintf("InitSockets!/n");
    CoInitialize(NULL);
    CCameraDS camera;
    if (!camera.OpenCamera(0,320,240,false))
    {
        RTMP_LogPrintf("Open Camera Error/n");
        return -1;
    }
    int nHeight=camera.GetHeight();
    int nWidth=camera.GetWidth();
    unsigned char * szRGBBuffer=new unsigned char[nHeight*nWidth * 3];
    RTMP_LogPrintf("Camera Open Scuess!  Picture Size[-x%d]/n",nWidth,nHeight);
    RTMP_debuglevel = RTMP_LOGINFO;
    RTMP *r;
    //char uri[]="rtmp://127.0.0.1/live/test";
    //char uri[]="rtmp://192.199.15.223/live/test";
    //char uri[]="rtmp://221.9.244.4/live/jltv";
    //char uri[]="rtmp://192.199.15.223/oflaDemo/red5StreamDemo";
    //char uri[]="rtmp://192.199.15.151/live/test";
    char uri[]="rtmp://127.0.0.1/live/zzj";
    r= RTMP_Alloc();
    RTMP_Init(r);
    RTMP_SetupURL(r, (char*)uri);
    RTMP_EnableWrite(r);
    RTMP_Connect(r, NULL);
    RTMP_ConnectStream(r,0);
    unsigned char szNalBuffer[1024*32];
    unsigned char szBodyBuffer[1024*32];
    x264_nal_t    *p264Nal;
    int            i264Nal;
    x264_param_t * p264Param;
    x264_picture_t * p264Pic;
    x264_t *p264Handle;    
    p264Param = new x264_param_t();
    p264Pic     = new x264_picture_t();
    memset(p264Pic,0,sizeof(x264_picture_t));
    x264_param_default(p264Param);    //set default param
    p264Param->i_threads=2;
    p264Param->i_width    = nWidth;    //set frame width
    p264Param->i_height    = nHeight;    //set frame height
    
    p264Param->b_cabac =0;
    p264Param->i_bframe =0;
    p264Param->b_interlaced=0;
    p264Param->rc.i_rc_method=X264_RC_ABR;//X264_RC_CQP
    p264Param->i_level_idc=21;
    p264Param->rc.i_bitrate=200;
    p264Param->i_fps_num=30;
    p264Param->i_keyint_max=p264Param->i_fps_num*3;
    if((p264Handle = x264_encoder_open(p264Param)) == NULL)
    {
        fprintf( stderr, "x264_encoder_open failed/n" );
        return -2;
    }
    bs_t bs={0};
    x264_picture_alloc(p264Pic, X264_CSP_YV12, p264Param->i_width, p264Param->i_height);
    p264Pic->i_type = X264_TYPE_AUTO;
    x264_picture_t pic_out;
    RTMPPacket packet={0};
    memset(&packet,0,sizeof(RTMPPacket));
    packet.m_nChannel = 0x04;
    packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet.m_nTimeStamp = 0;
    packet.m_nInfoField2 = r->m_stream_id;
    packet.m_hasAbsTimestamp = 0;
    packet.m_body =(char *) szBodyBuffer;
    char * szTmp=(char *)szBodyBuffer;
    packet.m_packetType = RTMP_PACKET_TYPE_INFO;
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string(szTmp, "@setDataFrame" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string(szTmp, "onMetaData" );
    szTmp=put_byte(szTmp, AMF_OBJECT );
    szTmp=put_amf_string( szTmp, "author" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_amf_string( szTmp, "copyright" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_amf_string( szTmp, "description" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_amf_string( szTmp, "keywords" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_amf_string( szTmp, "rating" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_amf_string( szTmp, "presetname" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "Custom" );
    szTmp=put_amf_string( szTmp, "width" );
    szTmp=put_amf_double( szTmp, p264Param->i_width );
    szTmp=put_amf_string( szTmp, "width" );
    szTmp=put_amf_double( szTmp, p264Param->i_width );
    szTmp=put_amf_string( szTmp, "height" );
    szTmp=put_amf_double( szTmp, p264Param->i_height );
    szTmp=put_amf_string( szTmp, "framerate" );
    szTmp=put_amf_double( szTmp, (double)p264Param->i_fps_num / p264Param->i_fps_den );
    szTmp=put_amf_string( szTmp, "videocodecid" );
    szTmp=put_byte(szTmp, AMF_STRING );
    szTmp=put_amf_string( szTmp, "avc1" );
    szTmp=put_amf_string( szTmp, "videodatarate" );
    szTmp=put_amf_double( szTmp, p264Param->rc.i_bitrate );
    szTmp=put_amf_string( szTmp, "avclevel" );
    szTmp=put_amf_double( szTmp, p264Param->i_level_idc );
    szTmp=put_amf_string( szTmp, "avcprofile" );
    szTmp=put_amf_double( szTmp, 0x42 );
    szTmp=put_amf_string( szTmp, "videokeyframe_frequency" );
    szTmp=put_amf_double( szTmp, 3 );
    szTmp=put_amf_string( szTmp, "" );
    szTmp=put_byte( szTmp, AMF_OBJECT_END );
    packet.m_nBodySize=szTmp-(char *)szBodyBuffer;
    RTMP_SendPacket(r,&packet,1);
    packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;    
    szBodyBuffer[ 0]=0x17;
    szBodyBuffer[ 1]=0x00;
    szBodyBuffer[ 2]=0x00;
    szBodyBuffer[ 3]=0x00;
    szBodyBuffer[ 4]=0x00;
    szBodyBuffer[ 5]=0x01;
    szBodyBuffer[ 6]=0x42;
    szBodyBuffer[ 7]=0xC0;
    szBodyBuffer[ 8]=0x15;
    szBodyBuffer[ 9]=0x03;
    szBodyBuffer[10]=0x01;
    szTmp=(char *)szBodyBuffer+11;
    short slen=0;
    bs_init(&bs,szNalBuffer,16);//初始话bs
    x264_sps_write(&bs, p264Handle->sps);//读取编码器的SPS
    slen=bs.p-bs.p_start+1;//spslen(short)
    slen=htons(slen);
    memcpy(szTmp,&slen,sizeof(short));
    szTmp+=sizeof(short);
    *szTmp=0x67;
    szTmp+=1;
    memcpy(szTmp,bs.p_start,bs.p-bs.p_start);
    szTmp+=bs.p-bs.p_start;
    *szTmp=0x01;
    szTmp+=1;
    bs_init(&bs,szNalBuffer,16);//初始话bs
    x264_pps_write(&bs, p264Handle->pps);//读取编码器的PPS
    slen=bs.p-bs.p_start+1;//spslen(short)
    slen=htons(slen);
    memcpy(szTmp,&slen,sizeof(short));
    szTmp+=sizeof(short);
    *szTmp=0x68;
    szTmp+=1;
    memcpy(szTmp,bs.p_start,bs.p-bs.p_start);
    szTmp+=bs.p-bs.p_start;
    packet.m_nBodySize=szTmp-(char *)szBodyBuffer;
    RTMP_SendPacket(r,&packet,0);
    unsigned int nTimes=0;
    unsigned int oldTick=GetTickCount();
    unsigned int newTick=0;
    packet.m_nTimeStamp=0;
    
    while(true)
    {
        szBodyBuffer[ 0]=0x17;
        szBodyBuffer[ 1]=0x01;
        szBodyBuffer[ 2]=0x00;
        szBodyBuffer[ 3]=0x00;
        szBodyBuffer[ 4]=0x42;
        unsigned char * szTmp=szBodyBuffer+5;
        unsigned  char * pNal=szNalBuffer;
        nTimes++;
        int nFramsInPack=0;
        while(true)
        {
            nFramsInPack++;
            unsigned char * pCameraBuf = camera.QueryFrame();
            if (!pCameraBuf)
            {
                return -1;
            }
            for(int ii=0;ii
            {
                memcpy(szRGBBuffer+(nWidth*3)*(nHeight-ii-1),pCameraBuf+(nWidth*3)*ii,nWidth*3);
                //memcpy(pCameraBuf+nWidth*(nHeight-ii-1),pCameraBuf+nWidth*ii,nWidth*3);
                //memcpy(szLineBuffer,pCameraBuf+nWidth*(nHeight-ii-1),nWidth*3);
            }
            ConvertRGB2YUV(nWidth,nHeight,szRGBBuffer,p264Pic->img.plane[0]);
            //memcpy(p264Pic->img.plane[0],szNalBuffer,nWidth*nHeight);
            //memcpy(p264Pic->img.plane[1],szNalBuffer+nWidth*nHeight,nWidth*nHeight/4);
            //memcpy(p264Pic->img.plane[2],szNalBuffer+nWidth*nHeight*5/4,nWidth*nHeight/4);
            
            if( x264_encoder_encode( p264Handle, &p264Nal, &i264Nal, p264Pic ,&pic_out) < 0 )
            {
                fprintf( stderr, "x264_encoder_encode failed/n" );
            }
            for( int i = 0; i < i264Nal; i++ )
            {
                int i_size;
                int i_data;
                i_data = 1024*32;
                if( ( i_size = x264_nal_encode( pNal, &i_data, 1, &p264Nal[i] ) ) > 0 )
                {
                    if ((pNal[4]&0x60)==0)
                    {
                        continue;
                    }
                    if (pNal[4]==0x67)
                    {
                        continue;
                    }
                    if (pNal[4]==0x68)
                    {
                        continue;
                    }
                    memmove(pNal,pNal+4,i_size-4);
                    pNal+=i_size-4;
                }
                else if( i_size < 0 )
                {
                    fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size );
                }
            }
            unsigned int nSize=pNal-szNalBuffer;
            packet.m_nBodySize=nSize+9;
            if (i264Nal>1)
            {
                szBodyBuffer[ 0]=0x17;
            }
            else
            {
                szBodyBuffer[ 0]=0x27;
            }
            put_be32((char *)szBodyBuffer+5,nSize);
            memcpy(szBodyBuffer+9,szNalBuffer,pNal-szNalBuffer);
            RTMP_SendPacket(r,&packet,0);
            Sleep(20);
            newTick=GetTickCount();
            //RTMP_LogStatus("/rInfo NAUL Type:0xx size: ] Tick:d d",szNalBuffer[0], nSize,33-nSleep,GetTickCount()-oldTick+nSleep);
            packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
            packet.m_nTimeStamp+=newTick-oldTick;
            oldTick=newTick;
            break;
        }
    }
    return 0;
}

(转)H264通过RTMP发布 V2.0 (Red5 Wowza 测试通过)的更多相关文章

  1. 怎样在IDEA中使用JUnit4和JUnitGenerator V2.0自动生成测试模块

     因为项目的需要,所以研究了一下自动生成测试代码.将经验记录下来,总会有用的.我个人认为,好记性不如多做笔记多反思总结. 1.    前提条件 开发环境已正确配置 工程已解决JUnit依赖关系(pom ...

  2. 25.怎样在IDEA中使用JUnit4和JUnitGenerator V2.0自动生成测试模块

    转自:https://blog.csdn.net/wangyj1992/article/details/78387728 因为项目的需要,所以研究了一下自动生成测试代码.将经验记录下来,总会有用的.我 ...

  3. D盾 v2.0.6.42 测试记录

    0x01 前言 之前发了一篇博客<Bypass D盾_IIS防火墙SQL注入防御(多姿势)>,D哥第一时间联系我,对问题进行修复.这段时间与D哥聊了挺多关于D盾这款产品的话题,实在是很佩服 ...

  4. Restful.Data v2.0发布,谢谢你们的支持和鼓励

    v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...

  5. iBox v2.0 发布,Web化仿iOS7界面/交互的JavaScirpt库

    iBox2 是一个仿 iOS 7 界面/交互的 JavaScirpt 库,它运行在 webkit 内核的移动浏览器之上,依赖 iScroll5,帮助开发者构建更接近 iOS 体验的 WebApp. 伴 ...

  6. QzzmServer v2.0正式版发布

                                 V2.1升级程序已发布,具体见下文                                首先,感谢网友的热情的测评及反馈,现Qzzm ...

  7. PCMM(人力资源能力成熟度模型)V2.0中英对照版发布

    PCMM中英版终于发布 时光荏苒,从当初的回眸到如今的回头,这才发现:坚守一份承诺是多么的不易! 一年多了,这份承载殷切期待的作品--<PCMM(人力资源能力成熟度模型)V2.0 (中英文对照版 ...

  8. go-wingui 2018 全新 v2.0 版本发布,包含重大更新!

    go-wingui 2018 全新 v2.0 版本发布,包含重大更新!使用新版CEF内核Chromium 63.0.3239.109,页面可以使用最新的css3,html5技术.使用delphi7重写 ...

  9. 【Beta】“北航社团帮”发布声明——小程序v2.0与网页端v1.0

    目录 Beta版本新功能 小程序v2.0新功能 新功能列表 功能详情图 新功能动图展示 网页端v1.0功能 登录方式 社团信息的修改 新闻的录入和修改 活动的录入和修改 这一版修复的缺陷 Beta版本 ...

随机推荐

  1. Ubuntu 下查看已安装的软件

    Ubuntu 下如何查看已安装的软件 1.查看安装的所有软件 dpkg -l 例如: dpkg -l | grep ftp 2.查看软件安装的路径 dpkg -L | grep ftp 也可以用 wh ...

  2. leetcode 之Search in Rotated Sorted Array(三)

    描述    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 ...

  3. cocos2d-x v2.2 IOS工程支持64-bit 遇坑记录

    修改缘由 由于 iPhone 5S的A7 CPU   iPhone 6(A8 CPU)都已经支持64-bit ARM 架构,据说64位处理器跑64代码会提高处理能力?因此二月一新提交appstore应 ...

  4. CSU 1355 地雷清除计划

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1355 好题,根本想不到是网络流. 模型如图: 假想从右上角到左下角有一条阻拦线,我们就是 ...

  5. Jmeter----请求的reponse结果中的某个参数作为JDBC Request的查询条件

    一.前言 数据库连接成功,若不会的查看:https://www.cnblogs.com/syw20170419/p/9832402.html 二.需求 将登录账号12608523691,接口的repo ...

  6. Win + Linux下Source Insight 替代方案

    需要阅读大量的系统源码,还有开源框架和好的源码等,需要寻求轻量,多快好省的editor, 最好有markdown语法的支持,支持重构,跳转调用,定义等... 自动补全... 目前看来,windows上 ...

  7. Java学习(基本语句,语法,变量)

    一.基本语法: public class Demo { //定义一个类 public static void main(String[] args) { //主方法,一切程序的起点 /* 在屏幕上打印 ...

  8. 【PAT】1012. 数字分类 (20)

    1012. 数字分类 (20) 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算 ...

  9. ps | grep app 命令不显示grep app本身进程的几种方式

    ps | grep app 命令不显示grep app本身进程的几种方式 使用ps命令查询进程,常常我们不想打印出"ps | grep app"这个当前进程,比如如下: [root ...

  10. Linux 下安装gmpy2

    GMP(GNU Multiple Precision Arithmetic Library,即GNU高精度算术运算库),它是一个开源的高精度运算库,其中不但有普通的整数.实数.浮点数的高精度运算,还有 ...