Exemplo n.º 1
0
static int
SendConnectResult(RTMP *r, double txn)
{
  RTMPPacket packet;
  char pbuf[384], *pend = pbuf+sizeof(pbuf);
  AMFObject obj;
  AMFObjectProperty p, op;
  AVal av;

  packet.m_nChannel = 0x03;     // control channel (invoke)
  packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */
  packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
  packet.m_nTimeStamp = 0;
  packet.m_nInfoField2 = 0;
  packet.m_hasAbsTimestamp = 0;
  packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;

  char *enc = packet.m_body;
  enc = AMF_EncodeString(enc, pend, &av__result);
  enc = AMF_EncodeNumber(enc, pend, txn);
  *enc++ = AMF_OBJECT;

  STR2AVAL(av, "FMS/3,5,1,525");
  enc = AMF_EncodeNamedString(enc, pend, &av_fmsVer, &av);
  enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 31.0);
  enc = AMF_EncodeNamedNumber(enc, pend, &av_mode, 1.0);
  *enc++ = 0;
  *enc++ = 0;
  *enc++ = AMF_OBJECT_END;

  *enc++ = AMF_OBJECT;

  STR2AVAL(av, "status");
  enc = AMF_EncodeNamedString(enc, pend, &av_level, &av);
  STR2AVAL(av, "NetConnection.Connect.Success");
  enc = AMF_EncodeNamedString(enc, pend, &av_code, &av);
  STR2AVAL(av, "Connection succeeded.");
  enc = AMF_EncodeNamedString(enc, pend, &av_description, &av);
  enc = AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, r->m_fEncoding);
#if 0
  STR2AVAL(av, "58656322c972d6cdf2d776167575045f8484ea888e31c086f7b5ffbd0baec55ce442c2fb");
  enc = AMF_EncodeNamedString(enc, pend, &av_secureToken, &av);
#endif
  STR2AVAL(p.p_name, "version");
  STR2AVAL(p.p_vu.p_aval, "3,5,1,525");
  p.p_type = AMF_STRING;
  obj.o_num = 1;
  obj.o_props = &p;
  op.p_type = AMF_OBJECT;
  STR2AVAL(op.p_name, "data");
  op.p_vu.p_object = obj;
  enc = AMFProp_Encode(&op, enc, pend);
  *enc++ = 0;
  *enc++ = 0;
  *enc++ = AMF_OBJECT_END;

  packet.m_nBodySize = enc - packet.m_body;

  return RTMP_SendPacket(r, &packet, FALSE);
}
Exemplo n.º 2
0
int SendPlayStop(RTMP *r)
{
    RTMPPacket packet;
    char pbuf[512], *pend = pbuf+sizeof(pbuf);

    packet.m_nChannel = 0x03;     // control channel (invoke)
    packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
    packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
    packet.m_nTimeStamp = 0;
    packet.m_nInfoField2 = 0;
    packet.m_hasAbsTimestamp = 0;
    packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;

    char *enc = packet.m_body;
    enc = AMF_EncodeString(enc, pend, &av_onStatus);
    enc = AMF_EncodeNumber(enc, pend, 0);
    *enc++ = AMF_NULL;
    *enc++ = AMF_OBJECT;

    enc = AMF_EncodeNamedString(enc, pend, &av_level, &av_status);
    enc = AMF_EncodeNamedString(enc, pend, &av_code, &av_NetStream_Play_Stop);
    enc = AMF_EncodeNamedString(enc, pend, &av_description, &av_Stopped_playing);
    enc = AMF_EncodeNamedString(enc, pend, &av_details, &r->Link.playpath);
    enc = AMF_EncodeNamedString(enc, pend, &av_clientid, &av_clientid);
    *enc++ = 0;
    *enc++ = 0;
    *enc++ = AMF_OBJECT_END;

    packet.m_nBodySize = enc - packet.m_body;
    return RTMP_SendPacket(r, &packet, FALSE);
}
Exemplo n.º 3
0
int CRtmpdSession::SendPacketBin( int format, int csi, int type, int ext, sqbind::CSqBinary *b, int nQueue )
{
	// Sanity checks
	if ( !b )
		return 0;

	// Must have a session
	if ( !m_session.m_sb.sb_socket )
		return 0;

	// Initialize packet
	oexZero( m_packet );

	// Initialize packet headers
	m_packet.m_nChannel = csi;
	m_packet.m_headerType = format;
	m_packet.m_packetType = type;
	m_packet.m_nInfoField2 = ext;
/*
	// Audio
	if ( 8 == type )
		m_packet.m_nTimeStamp = m_nTs++;
	// Video
	else if ( 9 == type )
		m_packet.m_nTimeStamp = m_nTs;
	else
*/		m_packet.m_nTimeStamp = 0;

	// Timestamps?
	m_packet.m_hasAbsTimestamp = ( 0 < m_nTs ) ? 1 : 0;

	sqbind::CSqBinary body;
	if ( !body.Allocate( RTMP_MAX_HEADER_SIZE + b->getUsed() + 128 ) )
		return 0;

	// Add padding byte for AMF3
	if ( 0x11 == type )
		body.setUsed( RTMP_MAX_HEADER_SIZE + 1 ),
		body.setUCHAR( RTMP_MAX_HEADER_SIZE, 0 );
	else
		body.setUsed( RTMP_MAX_HEADER_SIZE );

	// Append data
	body.Append( b );

	// Point the packet at the encoded variables
	m_packet.m_body = (char*)body.Ptr( RTMP_MAX_HEADER_SIZE );

	// Set body size
	m_packet.m_nBodySize = body.getUsed() - RTMP_MAX_HEADER_SIZE;

	// Send the packet
	return RTMP_SendPacket( &m_session, &m_packet, nQueue );
}
Exemplo n.º 4
0
int ExecuteAuthenticationDetails(RTMP *r, AMFObject *proplist, YLENGStream *yle) {
  long authResult = -1;
  int i;
  
  for (i=0; i<AMF_CountProp(proplist); i++) {
    AVal name;
    AMFObjectProperty *prop = AMF_GetProp(proplist, NULL, i);
    AMFProp_GetName(prop, &name);

    if (AVMATCH(&name, &av_locatedInBroadcastTerritory)) {
      yle->locatedInBroadcastTerritory = AMFProp_GetBoolean(prop);
    } else if (AVMATCH(&name, &av_randomAuth)) {
      authResult = ((long)AMFProp_GetNumber(prop) + 447537687) % 6834253;
    } else if (AVMATCH(&name, &av_tvFeeActivated)) {
      yle->tvFeeActivated = AMFProp_GetBoolean(prop);
    }
  }

  if (authResult != -1) {
    RTMPPacket packet;
    char pbuf[128], *pend = pbuf+sizeof(pbuf);

    packet.m_nChannel = 0x03;   // control channel
    packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet.m_packetType = 0x11; // FLEX MESSAGE
    packet.m_nTimeStamp = RTMP_GetTime();
    packet.m_nInfoField2 = 0;
    packet.m_hasAbsTimestamp = 0;

    packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
    char *enc = packet.m_body;
    *enc++ = 0x00;   // Unknown
    enc = AMF_EncodeString(enc, pend, &av_authenticateRandomNumber);
    enc = AMF_EncodeNumber(enc, pend, 0);
    *enc++ = AMF_NULL;
    enc = AMF_EncodeNumber(enc, pend, (double)authResult);

    packet.m_nBodySize = enc-packet.m_body;

    RTMP_Log(RTMP_LOGDEBUG, "sending authenticateRandomNumber");

    return RTMP_SendPacket(r, &packet, FALSE);
  }

  return FALSE;
}
Exemplo n.º 5
0
int RequestData(RTMP *r, YLENGStream *yle) {
  RTMPPacket packet;
  char pbuf[128], *pend = pbuf+sizeof(pbuf);
  AVal clipID;

  packet.m_nChannel = 0x03;   // control channel
  packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
  packet.m_packetType = 0x11; // FLEX MESSAGE
  packet.m_nTimeStamp = RTMP_GetTime();
  packet.m_nInfoField2 = 0;
  packet.m_hasAbsTimestamp = 0;

  packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
  char *enc = packet.m_body;
  *enc++ = 0x00;   // Unknown
  enc = AMF_EncodeString(enc, pend, &av_requestData);
  enc = AMF_EncodeNumber(enc, pend, 0);
  *enc++ = AMF_NULL;
  enc = AMF_EncodeString(enc, pend, &av_e0);

  if ((r->Link.lFlags & RTMP_LF_LIVE) != 0) {
    char *tmp = malloc(yle->clipID.av_len+12);
    strcpy(tmp, "streams/fi/");
    strncat(tmp, yle->clipID.av_val, yle->clipID.av_len);
    STR2AVAL(clipID, tmp);
    enc = AMF_EncodeString(enc, pend, &clipID);
    free(tmp);
  } else {
    char *tmp = malloc(yle->clipID.av_len+2);
    strcpy(tmp, "/");
    strncat(tmp, yle->clipID.av_val, yle->clipID.av_len);
    STR2AVAL(clipID, tmp);
    enc = AMF_EncodeString(enc, pend, &clipID);
    free(tmp);
  }

  if (!enc) {
    RTMP_Log(RTMP_LOGERROR, "Buffer too short in RequestData");
    return FALSE;
  }

  packet.m_nBodySize = enc-packet.m_body;

  return RTMP_SendPacket(r, &packet, FALSE);
}
Exemplo n.º 6
0
void LibRtmp::SendSetChunkSize(unsigned int chunkSize)
{
    RTMPPacket rtmp_pakt;
    RTMPPacket_Reset(&rtmp_pakt);
    RTMPPacket_Alloc(&rtmp_pakt, 4);

    rtmp_pakt.m_packetType = 0x01;
    rtmp_pakt.m_nChannel = 0x02;    // control channel
    rtmp_pakt.m_headerType = RTMP_PACKET_SIZE_LARGE;
    rtmp_pakt.m_nInfoField2 = 0;


    rtmp_pakt.m_nBodySize = 4;
    UI32ToBytes(rtmp_pakt.m_body, chunkSize);

    RTMP_SendPacket(rtmp_, &rtmp_pakt, 0);
    RTMPPacket_Free(&rtmp_pakt);
}
Exemplo n.º 7
0
bool LibRtmp::Send(const char* buf, int bufLen, int type, unsigned int timestamp)
{
    RTMPPacket rtmp_pakt;
    RTMPPacket_Reset(&rtmp_pakt);
    RTMPPacket_Alloc(&rtmp_pakt, bufLen);

    rtmp_pakt.m_packetType = type;
    rtmp_pakt.m_nBodySize = bufLen;
    rtmp_pakt.m_nTimeStamp = timestamp;
    rtmp_pakt.m_nChannel = 4;
    rtmp_pakt.m_headerType = RTMP_PACKET_SIZE_LARGE;
    rtmp_pakt.m_nInfoField2 = rtmp_->m_stream_id;
    memcpy(rtmp_pakt.m_body, buf, bufLen);

    int retval = RTMP_SendPacket(rtmp_, &rtmp_pakt, 0);
    RTMPPacket_Free(&rtmp_pakt);

    return !!retval;
}
Exemplo n.º 8
0
int SendResultNumber(RTMP *r, double txn, double ID)
{
    RTMPPacket packet;
    char pbuf[256], *pend = pbuf+sizeof(pbuf);

    packet.m_nChannel = 0x03;     // control channel (invoke)
    packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
    packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
    packet.m_nTimeStamp = 0;
    packet.m_nInfoField2 = 0;
    packet.m_hasAbsTimestamp = 0;
    packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;

    char *enc = packet.m_body;
    enc = AMF_EncodeString(enc, pend, &av__result);
    enc = AMF_EncodeNumber(enc, pend, txn);
    *enc++ = AMF_NULL;
    enc = AMF_EncodeNumber(enc, pend, ID);

    packet.m_nBodySize = enc - packet.m_body;

    return RTMP_SendPacket(r, &packet, FALSE);
}
Exemplo n.º 9
0
int CRtmpdSession::SendPacket2( int format, int csi, int type, int ext, sqbind::CSqMulti *m, int nQueue )
{
	// Sanity checks
	if ( !m || !m->size() )
		return 0;

	// Must have a session
	if ( !m_session.m_sb.sb_socket )
		return 0;

	// Initialize packet
	oexZero( m_packet );

	// Initialize packet headers
	m_packet.m_nChannel = csi;
	m_packet.m_headerType = format;
	m_packet.m_packetType = type;
	m_packet.m_nInfoField2 = ext;
/*
	// Audio
	if ( 8 == type )
		m_packet.m_nTimeStamp = m_nTs++;
	// Video
	else if ( 9 == type )
		m_packet.m_nTimeStamp = m_nTs;
	else
*/		m_packet.m_nTimeStamp = 0;

	// Timestamps?
	m_packet.m_hasAbsTimestamp = ( 0 < m_nTs ) ? 1 : 0;

	sqbind::CSqBinary body;
	if ( !body.Allocate( RTMP_MAX_HEADER_SIZE + 1024 ) )
		return 0;

	// Apparently, somewhere, RTMP_SendPacket() reaches backward
	// in the buffer, and apparently, it's by design.
	// I'm not sure how to feel about that ...

	// Add padding byte for AMF3
	if ( 0x11 == type )
		body.setUsed( RTMP_MAX_HEADER_SIZE + 1 ),
		body.setUCHAR( RTMP_MAX_HEADER_SIZE, 0 );
	else
		body.setUsed( RTMP_MAX_HEADER_SIZE );

	// Is it a raw buffer?
	if ( m->isset( "body" ) )
		body.appendString( (*m)[ "body" ].str() );

	// Serialize our data
	else if ( !SerializePacket( &body, m, 0 ) )
		return 0;

	// Point the packet at the encoded variables
	m_packet.m_body = (char*)body.Ptr( RTMP_MAX_HEADER_SIZE );

	// Set body size
	m_packet.m_nBodySize = body.getUsed() - RTMP_MAX_HEADER_SIZE;

	// Send the packet
	return RTMP_SendPacket( &m_session, &m_packet, nQueue );
}
Exemplo n.º 10
0
void RTMPPublisher::BeginPublishingInternal()
{
    RTMPPacket packet;

    char pbuf[2048], *pend = pbuf+sizeof(pbuf);

    packet.m_nChannel = 0x03;     // control channel (invoke)
    packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet.m_packetType = RTMP_PACKET_TYPE_INFO;
    packet.m_nTimeStamp = 0;
    packet.m_nInfoField2 = rtmp->m_stream_id;
    packet.m_hasAbsTimestamp = TRUE;
    packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;

    char *enc = packet.m_body;
    enc = AMF_EncodeString(enc, pend, &av_setDataFrame);
    enc = AMF_EncodeString(enc, pend, &av_onMetaData);
    enc = App->EncMetaData(enc, pend);

    packet.m_nBodySize = enc - packet.m_body;
    if(!RTMP_SendPacket(rtmp, &packet, FALSE))
    {
        App->PostStopMessage();
        return;
    }

    //----------------------------------------------

    List<BYTE> packetPadding;
    DataPacket mediaHeaders;

    //----------------------------------------------

    packet.m_nChannel = 0x05; // source channel
    packet.m_packetType = RTMP_PACKET_TYPE_AUDIO;

    App->GetAudioHeaders(mediaHeaders);

    packetPadding.SetSize(RTMP_MAX_HEADER_SIZE);
    packetPadding.AppendArray(mediaHeaders.lpPacket, mediaHeaders.size);

    packet.m_body = (char*)packetPadding.Array()+RTMP_MAX_HEADER_SIZE;
    packet.m_nBodySize = mediaHeaders.size;
    if(!RTMP_SendPacket(rtmp, &packet, FALSE))
    {
        App->PostStopMessage();
        return;
    }

    //----------------------------------------------

    packet.m_nChannel = 0x04; // source channel
    packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;

    App->GetVideoHeaders(mediaHeaders);

    packetPadding.SetSize(RTMP_MAX_HEADER_SIZE);
    packetPadding.AppendArray(mediaHeaders.lpPacket, mediaHeaders.size);

    packet.m_body = (char*)packetPadding.Array()+RTMP_MAX_HEADER_SIZE;
    packet.m_nBodySize = mediaHeaders.size;
    if(!RTMP_SendPacket(rtmp, &packet, FALSE))
    {
        App->PostStopMessage();
        return;
    }
}
Exemplo n.º 11
0
void RTMPPublisher::SendLoop()
{
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
    while(WaitForSingleObject(hSendSempahore, INFINITE) == WAIT_OBJECT_0)
    {
        while(true)
        {
            OSEnterMutex(hDataMutex);
            if(queuedPackets.Num() == 0)
            {
                OSLeaveMutex(hDataMutex);
                break;
            }

            List<BYTE> packetData;
            PacketType type       = queuedPackets[0].type;
            DWORD      timestamp  = queuedPackets[0].timestamp;
            packetData.TransferFrom(queuedPackets[0].data);

            currentBufferSize -= packetData.Num();

            queuedPackets.Remove(0);

            OSLeaveMutex(hDataMutex);

            //--------------------------------------------

            RTMPPacket packet;
            packet.m_nChannel = (type == PacketType_Audio) ? 0x5 : 0x4;
            packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
            packet.m_packetType = (type == PacketType_Audio) ? RTMP_PACKET_TYPE_AUDIO : RTMP_PACKET_TYPE_VIDEO;
            packet.m_nTimeStamp = timestamp;
            packet.m_nInfoField2 = rtmp->m_stream_id;
            packet.m_hasAbsTimestamp = TRUE;

            packet.m_nBodySize = packetData.Num()-RTMP_MAX_HEADER_SIZE;
            packet.m_body = (char*)packetData.Array()+RTMP_MAX_HEADER_SIZE;

            //QWORD sendTimeStart = OSGetTimeMicroseconds();
            if(!RTMP_SendPacket(rtmp, &packet, FALSE))
            {
                //should never reach here with the new shutdown sequence.
                RUNONCE Log(TEXT("RTMP_SendPacket failure, should not happen!"));
                if(!RTMP_IsConnected(rtmp))
                {
                    App->PostStopMessage();
                    break;
                }
            }

            //----------------------------------------------------------

            /*outputRateSize += packetData.Num();
            packetSizeRecord << PacketTimeSize(timestamp, packetData.Num());
            if(packetSizeRecord.Num())
            {
                UINT packetID=0;
                for(; packetID<packetSizeRecord.Num(); packetID++)
                {
                    if(timestamp-packetSizeRecord[packetID].timestamp < outputRateWindowTime)
                        break;
                    else
                        outputRateSize -= packetSizeRecord[packetID].size;
                }

                if(packetID != 0)
                    packetSizeRecord.RemoveRange(0, packetID);
            }*/

            //bytesSent += packetData.Num();
        }

        if (bStopping && WaitForSingleObject(hSendLoopExit, 0) == WAIT_OBJECT_0)
            return;
    }
}
Exemplo n.º 12
0
//Publish using RTMP_SendPacket()  
int publish_using_packet(){  
	RTMP *rtmp=NULL;                             
	RTMPPacket *packet=NULL;  
	uint32_t start_time=0;  
	uint32_t now_time=0;  
	//the timestamp of the previous frame  
	long pre_frame_time=0;  
	long lasttime=0;  
	int bNextIsKey=1;  
	uint32_t preTagsize=0;  

	//packet attributes  
	uint32_t type=0;                          
	uint32_t datalength=0;             
	uint32_t timestamp=0;             
	uint32_t streamid=0;                          

	FILE*fp=NULL;  
	fp=fopen("../live.flv","rb");  
	if (!fp){  
		RTMP_LogPrintf("Open File Error.\n");  
	//	CleanupSockets();  
		return -1;  
	}  

	/* set log level */  
	//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
	//RTMP_LogSetLevel(loglvl);  

//	if (!InitSockets()){  
//		RTMP_LogPrintf("Init Socket Err\n");  
//		return -1;  
//	}  

	rtmp=RTMP_Alloc();  
	RTMP_Init(rtmp);  
	//set connection timeout,default 30s  
	rtmp->Link.timeout=5;                        
	if(!RTMP_SetupURL(rtmp,"rtmp://101.251.251.93:1935/myapp/mystream"))  
	{  
		RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	//if unable,the AMF command would be 'play' instead of 'publish'  
	RTMP_EnableWrite(rtmp);       

	if (!RTMP_Connect(rtmp,NULL)){  
		RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	if (!RTMP_ConnectStream(rtmp,0)){  
		RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
		RTMP_Close(rtmp);  
		RTMP_Free(rtmp);  
//		CleanupSockets();  
		return -1;  
	}  

	packet=(RTMPPacket*)malloc(sizeof(RTMPPacket));  
	RTMPPacket_Alloc(packet,1024*64);  
	RTMPPacket_Reset(packet);  

	packet->m_hasAbsTimestamp = 0;          
	packet->m_nChannel = 0x04;  
	packet->m_nInfoField2 = rtmp->m_stream_id;  

	RTMP_LogPrintf("Start to send data ...\n");  

	//jump over FLV Header  
	fseek(fp,9,SEEK_SET);       
	//jump over previousTagSizen  
	fseek(fp,4,SEEK_CUR);     
	start_time=RTMP_GetTime();  
	while(1)  
	{  
		if((((now_time=RTMP_GetTime())-start_time)  
					<(pre_frame_time)) && bNextIsKey){          
			//wait for 1 sec if the send process is too fast  
			//this mechanism is not very good,need some improvement  
			if(pre_frame_time>lasttime){  
				RTMP_LogPrintf("TimeStamp:%8lu ms\n",pre_frame_time);  
				lasttime=pre_frame_time;  
			}  
			sleep(1);  
			continue;  
		}  

		//not quite the same as FLV spec  
		if(!ReadU8(&type,fp))       
			break;  
		if(!ReadU24(&datalength,fp))  
			break;  
		if(!ReadTime(&timestamp,fp))  
			break;  
		if(!ReadU24(&streamid,fp))  
			break;  

		if (type!=0x08&&type!=0x09){  
			//jump over non_audio and non_video frame,  
			//jump over next previousTagSizen at the same time  
			fseek(fp,datalength+4,SEEK_CUR);  
			continue;  
		}  

		if(fread(packet->m_body,1,datalength,fp)!=datalength)  
			break;  

		packet->m_headerType = RTMP_PACKET_SIZE_LARGE;  
		packet->m_nTimeStamp = timestamp;  
		packet->m_packetType = type;  
		packet->m_nBodySize  = datalength;  
		pre_frame_time=timestamp;  

		if (!RTMP_IsConnected(rtmp)){  
			RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
			break;  
		}  
		if (!RTMP_SendPacket(rtmp,packet,0)){  
			RTMP_Log(RTMP_LOGERROR,"Send Error\n");  
			break;  
		}  

		if(!ReadU32(&preTagsize,fp))  
			break;  

		if(!PeekU8(&type,fp))  
			break;  
		if(type==0x09){  
			if(fseek(fp,11,SEEK_CUR)!=0)  
				break;  
			if(!PeekU8(&type,fp)){  
				break;  
			}  
			if(type==0x17)  
				bNextIsKey=1;  
			else  
				bNextIsKey=0;  

			fseek(fp,-11,SEEK_CUR);  
		}  
	}                 

	RTMP_LogPrintf("\nSend Data Over\n");  

	if(fp)  
		fclose(fp);  

	if (rtmp!=NULL){  
		RTMP_Close(rtmp);          
		RTMP_Free(rtmp);   
		rtmp=NULL;  
	}  
	if (packet!=NULL){  
		RTMPPacket_Free(packet);      
		free(packet);  
		packet=NULL;  
	}  

//	CleanupSockets();  
	return 0;  
}  
Exemplo n.º 13
0
void RTMPPublisher::SendLoop()
{
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
    while(WaitForSingleObject(hSendSempahore, INFINITE) == WAIT_OBJECT_0)
    {
        /*//--------------------------------------------
        // read

        DWORD pendingBytes = 0;
        ioctlsocket(rtmp->m_sb.sb_socket, FIONREAD, &pendingBytes);
        if(pendingBytes)
        {
            RTMPPacket packet;
            zero(&packet, sizeof(packet));

            while(RTMP_ReadPacket(rtmp, &packet) && !RTMPPacket_IsReady(&packet) && RTMP_IsConnected(rtmp));

            if(!RTMP_IsConnected(rtmp))
            {
                App->PostStopMessage();
                bStopping = true;
                break;
            }

            RTMPPacket_Free(&packet);
        }*/

        //--------------------------------------------
        // send

        while(true)
        {
            if(bStopping)
                return;

            OSEnterMutex(hDataMutex);
            if(queuedPackets.Num() == 0)
            {
                OSLeaveMutex(hDataMutex);
                break;
            }

            List<BYTE> packetData;
            PacketType type       = queuedPackets[0].type;
            DWORD      timestamp  = queuedPackets[0].timestamp;
            packetData.TransferFrom(queuedPackets[0].data);

            currentBufferSize -= packetData.Num();

            queuedPackets.Remove(0);

            OSLeaveMutex(hDataMutex);

            //--------------------------------------------

            RTMPPacket packet;
            packet.m_nChannel = (type == PacketType_Audio) ? 0x5 : 0x4;
            packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
            packet.m_packetType = (type == PacketType_Audio) ? RTMP_PACKET_TYPE_AUDIO : RTMP_PACKET_TYPE_VIDEO;
            packet.m_nTimeStamp = timestamp;
            packet.m_nInfoField2 = rtmp->m_stream_id;
            packet.m_hasAbsTimestamp = TRUE;

            packet.m_nBodySize = packetData.Num()-RTMP_MAX_HEADER_SIZE;
            packet.m_body = (char*)packetData.Array()+RTMP_MAX_HEADER_SIZE;

            //QWORD sendTimeStart = OSGetTimeMicroseconds();
            if(!RTMP_SendPacket(rtmp, &packet, FALSE))
            {
                if(!RTMP_IsConnected(rtmp))
                {
                    App->PostStopMessage();
                    bStopping = true;
                    break;
                }

                RUNONCE Log(TEXT("okay, this is strange"));
            }

            //----------------------------------------------------------

            /*outputRateSize += packetData.Num();
            packetSizeRecord << PacketTimeSize(timestamp, packetData.Num());
            if(packetSizeRecord.Num())
            {
                UINT packetID=0;
                for(; packetID<packetSizeRecord.Num(); packetID++)
                {
                    if(timestamp-packetSizeRecord[packetID].timestamp < outputRateWindowTime)
                        break;
                    else
                        outputRateSize -= packetSizeRecord[packetID].size;
                }

                if(packetID != 0)
                    packetSizeRecord.RemoveRange(0, packetID);
            }*/

            //bytesSent += packetData.Num();
        }
    }
}