예제 #1
0
int MediaBridgeSession::SendAudio()
{
	AudioCodec::Type rtmpAudioCodec;
	RTPPacket	 packet(MediaFrame::Audio,rtpAudioCodec,rtpAudioCodec);
	QWORD lastAudioTs = 0;
	DWORD frameTime=0;

	Log(">SendAudio\n");

	//While sending audio
	while (sendingAudio)
	{
		//Wait for next audio
		if (!audioFrames.Wait(0))
			//Check again
			continue;

		//Get audio grame
		RTMPAudioFrame* audio = audioFrames.Pop();
		//check
		if (!audio)
			//Again
			continue;
		//Get timestamp
		QWORD ts = audio->GetTimestamp();
		//Get delay
		QWORD diff = 0;
		//If it is the first frame
		if (lastAudioTs)
			//Calculate it
			diff = ts - lastAudioTs;
		//Check diff
		if (diff<40)
			//Set it to only one frame of 20 ms
			diff = 20;
		//Set the last audio timestamp
		lastAudioTs = ts;
		//Get codec type
		switch(audio->GetAudioCodec())
		{
			case RTMPAudioFrame::SPEEX:
				//Set codec
				rtmpAudioCodec = AudioCodec::SPEEX16;
				break;
			case RTMPAudioFrame::NELLY:
				//Set codec type
				rtmpAudioCodec = AudioCodec::NELLY11;
				break;
			default:
				continue;
		}
		//Check rtp type
		if (rtpAudioCodec!=rtmpAudioCodec)
		{
			BYTE rtp[MTU+SRTP_MAX_TRAILER_LEN] ZEROALIGNEDTO32;
			DWORD rtpSize = RTPPAYLOADSIZE;
			DWORD rtpLen = 0;
			SWORD raw[512];
			DWORD rawSize = 512;
			DWORD rawLen = 0;
			//Check if we have a decoder
			if (!rtmpAudioDecoder || rtmpAudioDecoder->type!=rtmpAudioCodec)
			{
				//Check
				if (rtmpAudioDecoder)
					//Delete old one
					delete(rtmpAudioDecoder);
				//Create new one
				rtmpAudioDecoder = AudioCodecFactory::CreateDecoder(rtmpAudioCodec);
			}
			//Get data
			BYTE *data = audio->GetMediaData();
			//Get size
			DWORD size = audio->GetMediaSize();
			//Decode it until no frame is found
			while ((rawLen = rtmpAudioDecoder->Decode(data,size,raw,rawSize))>0)
			{
				//Check size
				if (rawLen>0)
				{
					//Rencode ig
					rtpLen = rtpAudioEncoder->Encode(raw,rawLen,rtp,rtpSize);
					//Send
					if (rtpAudioCodec==AudioCodec::SPEEX16)
					{
						//Send rtp packet
						//FIX!!  rtpAudio.SendAudioPacket(rtp,rtpLen,diff*16);
					} else {
						//Send rtp packet
						//FIX!! rtpAudio.SendAudioPacket(rtp,rtpLen,diff*8);
					}
				}
				//Set diff
				diff = 20;
				//Remove size
				size = 0;
			}
		} else {
			//Set data
			packet.SetPayload(audio->GetMediaData(),audio->GetMediaSize());
			//Send rtp packet
			rtpAudio.SendPacket(packet);
		}
		//Delete audio
		delete(audio);
	}

	Log("<SendAudio\n");

	return 1;
}
예제 #2
0
/****************************************
* RecAudio
*	Obtiene los packetes y los muestra
*****************************************/
int MediaBridgeSession::RecAudio()
{
	DWORD		firstAudio = 0;
	DWORD		timeStamp=0;
	DWORD		firstTS = 0;
	SWORD		raw[512];
	DWORD		rawSize = 512;
	DWORD		rawLen;

	//Create new audio frame
	RTMPAudioFrame  *audio = new RTMPAudioFrame(0,RTPPAYLOADSIZE);

	Log(">RecAudio\n");

	//Mientras tengamos que capturar
	while(receivingAudio)
	{
		//Obtenemos el paquete
		RTPPacket *packet = rtpAudio.GetPacket();

		//Check
		if (!packet)
			//Next
			continue;

		//Get type
		AudioCodec::Type codec = (AudioCodec::Type)packet->GetCodec();

		//Check rtp type
		if (codec==AudioCodec::SPEEX16)
		{
			//TODO!!!!
		}

		//Check if we have a decoder
		if (!rtpAudioDecoder || rtpAudioDecoder->type!=codec)
		{
			//Check
			if (rtpAudioDecoder)
				//Delete old one
				delete(rtpAudioDecoder);
			//Create new one
			rtpAudioDecoder = AudioCodecFactory::CreateDecoder(codec);
		}

		//Decode it
		rawLen = rtpAudioDecoder->Decode(packet->GetMediaData(),packet->GetMediaLength(),raw,rawSize);

		//Delete packet
		delete(packet);

		//Rencode it
		DWORD len;

		while((len=rtmpAudioEncoder->Encode(raw,rawLen,audio->GetMediaData(),audio->GetMaxMediaSize()))>0)
		{
			//REset
			rawLen = 0;

			//Set length
			audio->SetMediaSize(len);

			switch(rtmpAudioEncoder->type)
			{
				case AudioCodec::SPEEX16:
					//Set RTMP data
					audio->SetAudioCodec(RTMPAudioFrame::SPEEX);
					audio->SetSoundRate(RTMPAudioFrame::RATE11khz);
					audio->SetSamples16Bits(1);
					audio->SetStereo(0);
					break;
				case AudioCodec::NELLY8:
					//Set RTMP data
					audio->SetAudioCodec(RTMPAudioFrame::NELLY8khz);
					audio->SetSoundRate(RTMPAudioFrame::RATE11khz);
					audio->SetSamples16Bits(1);
					audio->SetStereo(0);
					break;
				case AudioCodec::NELLY11:
					//Set RTMP data
					audio->SetAudioCodec(RTMPAudioFrame::NELLY);
					audio->SetSoundRate(RTMPAudioFrame::RATE11khz);
					audio->SetSamples16Bits(1);
					audio->SetStereo(0);
					break;
			}

			//If it is first
			if (!firstTS)
			{
				//Get first audio time
				firstAudio = getDifTime(&first)/1000;
				//It is first
				firstTS = timeStamp;
			}

			DWORD ts = firstAudio +(timeStamp-firstTS)/8;
			//Set timestamp
			audio->SetTimestamp(ts);

			//Send packet
			SendMediaFrame(audio);
		}
	}

	//Check
	if (audio)
		//Delete it
		delete(audio);

	Log("<RecAudio\n");
}
예제 #3
0
void RTMPMP4Stream::onMediaFrame(MediaFrame &media)
{
	//Depending on the media type
	switch (media.GetType())
	{
		case MediaFrame::Audio:
		{
			//Create rtmp frame
			RTMPAudioFrame *frame = new RTMPAudioFrame(0,512);
			//Get audio frame
			AudioFrame& audio = (AudioFrame&)media;
			//Check codec
			switch(audio.GetCodec())
			{
				case AudioCodec::PCMA:
				case AudioCodec::PCMU:
				{
					WORD raw[512];
					DWORD rawsize = 512;
					//Decode audio frame
					DWORD rawlen = decoder->Decode(audio.GetData(),audio.GetLength(),raw,rawsize);
					//Encode frame
					DWORD len = encoder->Encode(raw,rawlen,frame->GetMediaData(),frame->GetMaxMediaSize());
					//Set length
					frame->SetMediaSize(len);
					//Set type
					frame->SetAudioCodec(RTMPAudioFrame::SPEEX);
					frame->SetSoundRate(RTMPAudioFrame::RATE11khz);
					frame->SetSamples16Bits(1);
					frame->SetStereo(0);
					//Set timestamp
					frame->SetTimestamp(audio.GetTimeStamp()/8);
					break;
				}
				default:
					//Not supported
					return;
			}
			//Send it
			PlayMediaFrame(frame);
		}
		break;
		case MediaFrame::Video:
		{
			//Get video frame
			VideoFrame& video = (VideoFrame&)media;
			//Create rtmp frame
			RTMPVideoFrame *frame = new RTMPVideoFrame(video.GetTimeStamp()/90,video.GetLength());
			//Check codec
			switch(video.GetCodec())
			{
				case VideoCodec::H263_1996:
				case VideoCodec::H263_1998:
				#ifdef FLV1PARSER
				{
					//Create FLV1parser in case we need it
					flv1Parser *parser = new flv1Parser(frame->GetMediaData(),frame->GetMaxMediaSize());
					//Proccess
					if (!parser->FrameFromH263(video.GetData(),video.GetLength()))
						throw new std::exception();
					//Set lengtht
					frame->SetMediaSize(parser->GetSize());
					//If it is intra
					if (video.IsIntra())
						//Set type
						frame->SetFrameType(RTMPVideoFrame::INTRA);
					else
						//Set type
						frame->SetFrameType(RTMPVideoFrame::INTER);
					//Set type
					frame->SetVideoCodec(RTMPVideoFrame::FLV1);
				}
				#endif
					break;
				case VideoCodec::H264:
				{
					//Set Codec
					frame->SetVideoCodec(RTMPVideoFrame::AVC);
					//If it is intra
					if (video.IsIntra())
					{
						//Set type
						frame->SetFrameType(RTMPVideoFrame::INTRA);
						//If we have one
						if (desc)
						{
							//Create the fraame
							RTMPVideoFrame fdesc(frame->GetTimestamp(),desc);
							//Play it
							PlayMediaFrame(&fdesc);
						}
					} else {
						//Set type
						frame->SetFrameType(RTMPVideoFrame::INTER);
					}
					//Set NALU type
					frame->SetAVCType(1);
					//Set no delay
					frame->SetAVCTS(0);
					//Set Data
					frame->SetVideoFrame(video.GetData(),video.GetLength());
					break;
				}
				default:
					//Not supported
					return;
			}
			//Send it
			PlayMediaFrame(frame);
			//Delete it
			delete(frame);
		}
		break;
	}
}