您的位置:首页 > 其它

H264通过RTMP发布到Wowza

2011-04-02 16:45 295 查看
只是一个测试

时间戳的感觉有问题 毕竟在RTMP里只是一个24位的整型,如果超过了怎么办呢??



还有 感觉明明是发布上去了 用VLC通过RTSP也可以看到视频了



但是用FLASH看视频就是看不到 很奇怪



如果转载的话建议注明来源


http://blog.csdn.net/zblue78




// demo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"

#include "librtmp/rtmp_sys.h"
#include "librtmp/log.h"
#include "librtmp/amf.h"
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<l; i+=2)
		*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;	/* type: 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, _TCHAR* argv[])
{

	RTMP_LogPrintf("InitSockets!/n");
	if (!InitSockets()) return -1;
	RTMP_debuglevel = RTMP_LOGINFO;
	RTMP *r;
	//char uri[]="rtmp://127.0.0.1/live/mp4:test";
	char uri[]="rtmp://192.199.15.223/live/mp4:test";
	//char uri[]="rtmp://192.199.15.223/oflaDemo/mp4:test";
	//char uri[]="rtmp://192.199.15.151/live/test";
	//char uri[]="rtmp://221.9.244.4/live/test";
	r= RTMP_Alloc();
	RTMP_Init(r);
	RTMP_SetupURL(r, (char*)uri);
	RTMP_EnableWrite(r);
	RTMP_Connect(r, NULL);
	RTMP_ConnectStream(r,0);

	FILE *yuv=fopen("c://video-qcif.yuv","rb");
	FILE *dbg=fopen("C://video-qcif.h264","wb");
	unsigned char szNalBuffer[1024*32];
	//unsigned char szTempBuffer[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_width	= 176;	//set frame width
	p264Param->i_height	= 144;	//set frame height
	/*baseline level 1.1*/
	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=64;
	p264Param->i_keyint_max=20;
	p264Param->i_fps_num=15;
	//	p264Param->rc.i_qp_constant=22;
	if((p264Handle = x264_encoder_open(p264Param)) == NULL)
	{
		fprintf( stderr, "x264_encoder_open failed/n" );
		return -2;
	}
	bs_t bs={0};

	//fwrite(szNalBuffer,sizeof(char),bs.p-bs.p_start,dbg);
	x264_picture_alloc(p264Pic, X264_CSP_I420, 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, 66 ); 

	szTmp=put_amf_string( szTmp, "videokeyframe_frequency" );
	szTmp=put_amf_double( szTmp, 10 ); 
	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;	/* 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);//初始话bsW
	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);
	//packet.m_nTimeStamp=0xFFFFFF;
	unsigned int nTimes=0;
	//unsigned int old=GetTickCount();
	packet.m_nTimeStamp=0;
	while(dbg)
	{
		szBodyBuffer[ 0]=0x17;
		szBodyBuffer[ 1]=0x01;
		szBodyBuffer[ 2]=0x00;
		szBodyBuffer[ 3]=0x00;
		szBodyBuffer[ 4]=0x00;
		unsigned char * szTmp=szBodyBuffer+5;
		unsigned  char * pNal=szNalBuffer;
		//if (nTimes%5==0) 
		//{
			//	p264Pic->i_type=X264_TYPE_IDR;
		//}
		//else
		//{
			//	p264Pic->i_type=X264_TYPE_P;
		//}
		nTimes++;
		int nFramsInPack=0;
		while(true)
		{
			nFramsInPack++;
			int nCount;
			nCount=fread(p264Pic->img.plane[0],1,176*144,yuv);
			if (nCount<176*144)
			{
				fseek(yuv,SEEK_SET,0);
				continue;
			}
			nCount=fread(p264Pic->img.plane[1],1,176*144/4,yuv);
			if (nCount<176*144/4)
			{
				fseek(yuv,SEEK_SET,0);
				continue;
			}
			nCount=fread(p264Pic->img.plane[2],1,176*144/4,yuv);
			if (nCount<176*144/4)
			{
				fseek(yuv,SEEK_SET,0);
				continue;
			}
			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;
					}

					fwrite(pNal,sizeof(char),i_size,dbg);
					fflush(dbg);
					if (pNal[4]==0x67)
					{
						continue;
					}
					if (pNal[4]==0x68)
					{
						continue;
					}
					//unsigned long *len=(unsigned long *)szNalBuffer;
					//int nlen=htonl(i_size-4);
					//memcpy(szTmp,szNalBuffer,i_size);
					//memcpy(szTmp,&nlen,sizeof(unsigned long));
					memmove(pNal,pNal+4,i_size-4);
					fprintf( stderr, "Info x264_nal_encode[%d] Type:0x%x size: %d/n",i,*pNal, i_size);
					pNal+=i_size-4;
				}
				else if( i_size < 0 )
				{
					fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size );
				}
			}
			Sleep(67);
			unsigned int nSize=pNal-szNalBuffer;
			packet.m_nBodySize=nSize+9;
			if (i264Nal>1)
			{
				szBodyBuffer[ 0]=0x17;
				//packet.m_nTimeStamp=65;
				//	packet.m_nTimeStamp=0;
				//	packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
			}
			else
			{
				szBodyBuffer[ 0]=0x27;
				//	packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
				//	packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;	/* VIDEO */
			}
			//nSize=htonl(nSize);
			//memcpy(szTmp,&nSize,sizeof(unsigned int));
			//szTmp+=sizeof(unsigned int);
			//nSize=pNal-szNalBuffer;
			put_be32((char *)szBodyBuffer+5,nSize);
			memcpy(szBodyBuffer+9,szNalBuffer,pNal-szNalBuffer);
			RTMP_SendPacket(r,&packet,0);
			packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
			packet.m_nTimeStamp+=67;
			//old=GetTickCount();
			//fprintf( stderr, "Info RTMP_SendPacket[%d] /n",nFramsInPack);
			break;
		}

	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: