Esempio n. 1
0
bool MultiConf::AddBroadcastReceiver(RTMPStream *receiver)
{
	broadcast.AddReceiver(receiver);
	Participants::iterator itBroadcaster = participants.find(m_CurrentBroadCaster);
	if(itBroadcaster != participants.end())
	{
		RTPParticipant *broadCaster = (RTPParticipant*)itBroadcaster->second;
		Log("Send idr packet to newly broadcast reciever\n");
		IDRPacketSize idrPacketSize = broadCaster->GetIdrPacketSize();
		IDRPacket idrPacket = broadCaster->GetIdrPacket();
		DWORD currentTimeStamp = broadCaster->GetCurrentTimestamp();
		size_t packetSize = idrPacket.size();

		//Crete desc frame
		RTMPVideoFrame frameDesc(0,2048);
		//Send
		frameDesc.SetTimestamp(currentTimeStamp);
		//Set type
		frameDesc.SetVideoCodec(RTMPVideoFrame::AVC);
		//Set type
		frameDesc.SetFrameType(RTMPVideoFrame::INTRA);
		//Set NALU type
		frameDesc.SetAVCType(0);
		//Set no delay
		frameDesc.SetAVCTS(0);
		//Create description
		AVCDescriptor desc;
		//Set values
		desc.SetConfigurationVersion(1);
		//desc.SetAVCProfileIndication(0x42);
		//desc.SetProfileCompatibility(0x80);
		//desc.SetAVCLevelIndication(0x14);
		//desc.SetAVCProfileIndication(idrPacket[0][1]);
		//desc.SetProfileCompatibility(idrPacket[0][2]);
		//desc.SetAVCLevelIndication(idrPacket[0][3]);
		desc.SetAVCProfileIndication(0x64);
		desc.SetProfileCompatibility(0x00);
		desc.SetAVCLevelIndication(0x28);
		desc.SetNALUnitLength(3);
		desc.AddSequenceParameterSet(idrPacket[0],idrPacketSize[0]);
		desc.AddPictureParameterSet(idrPacket[1],idrPacketSize[1]);
		//Serialize
		DWORD len = desc.Serialize(frameDesc.GetMediaData(),frameDesc.GetMaxMediaSize());
		//Set size
		frameDesc.SetMediaSize(len);
		//broadcast.OnPublishedFrame(0, &frameDesc);
		receiver->PlayMediaFrame(&frameDesc);
		frameDesc.Dump();

		RTMPVideoFrame frame(0,65535);
		//Set codec
		frame.SetVideoCodec(RTMPVideoFrame::AVC);
		//Set NALU type
		frame.SetAVCType(1);
		//Set no delay
		frame.SetAVCTS(0);
		frame.SetTimestamp(currentTimeStamp);
		frame.SetFrameType(RTMPVideoFrame::INTRA);
		VideoFrame *videoFrame;
		RTPDepacketizer *depacketizer = RTPDepacketizer::Create( MediaFrame::Video, VideoCodec::H264);
		for(int i = 0; i < packetSize; i++) {
			BYTE *packet = idrPacket[i];
			int packet_size = idrPacketSize[i];
			videoFrame = (VideoFrame *)depacketizer->AddPayload(packet,packet_size);
		}
		frame.SetVideoFrame(videoFrame->GetData(), videoFrame->GetLength());
		receiver->PlayMediaFrame(&frame);
		frame.Dump();
		delete depacketizer;
		
	}
	
	return true;
}
Esempio n. 2
0
int FLVEncoder::EncodeVideo()
{
	timeval prev;

	//Start
	Log(">FLVEncoder  encode video\n");

	//Allocate media frame
	RTMPVideoFrame frame(0,262143);

	//Check codec
	switch(videoCodec)
	{
		case VideoCodec::SORENSON:
			//Ser Video codec
			frame.SetVideoCodec(RTMPVideoFrame::FLV1);
			break;
		case VideoCodec::H264:
			//Ser Video codec
			frame.SetVideoCodec(RTMPVideoFrame::AVC);
			//Set NAL type
			frame.SetAVCType(RTMPVideoFrame::AVCNALU);
			//No delay
			frame.SetAVCTS(0);
			break;
		default:
			return Error("-Wrong codec type %d\n",videoCodec);
	}
	
	//Create the encoder
	VideoEncoder *encoder = VideoCodecFactory::CreateEncoder(videoCodec,videoProperties);

	///Set frame rate
	encoder->SetFrameRate(fps,bitrate,intra);

	//Set dimensions
	encoder->SetSize(width,height);

	//Start capturing
	videoInput->StartVideoCapture(width,height,fps);

	//The time of the first one
	gettimeofday(&prev,NULL);

	//No wait for first
	DWORD frameTime = 0;

	Log(">FLVEncoder encode vide\n");

	//Mientras tengamos que capturar
	while(encodingVideo)
	{
		//Nos quedamos con el puntero antes de que lo cambien
		BYTE* pic=videoInput->GrabFrame(frameTime);
		
		//Ensure we are still encoding
		if (!encodingVideo)
			break;

		//Check pic
		if (!pic)
			continue;

		//Check if we need to send intra
		if (sendFPU)
		{
			//Set it
			encoder->FastPictureUpdate();
			//Do not send anymore
			sendFPU = false;
		}

		//Encode next frame
		VideoFrame *encoded = encoder->EncodeFrame(pic,videoInput->GetBufferSize());

		//Check
		if (!encoded)
			break;

		//Check size
		if (frame.GetMaxMediaSize()<encoded->GetLength())
		{
			//Not enougth space
			Error("Not enought space to copy FLV encodec frame [frame:%d,encoded:%d",frame.GetMaxMediaSize(),encoded->GetLength());
			//NExt
			continue;
		}

		//Check
		if (frameTime)
		{
			timespec ts;
			//Lock
			pthread_mutex_lock(&mutex);
			//Calculate timeout
			calcAbsTimeout(&ts,&prev,frameTime);
			//Wait next or stopped
			int canceled  = !pthread_cond_timedwait(&cond,&mutex,&ts);
			//Unlock
			pthread_mutex_unlock(&mutex);
			//Check if we have been canceled
			if (canceled)
				//Exit
				break;
		}
		//Set sending time of previous frame
		getUpdDifTime(&prev);

		//Set timestamp
		encoded->SetTimestamp(getDifTime(&first)/1000);

		//Set next one
		frameTime = 1000/fps;

		//Set duration
		encoded->SetDuration(frameTime);
		
		//Get full frame
		frame.SetVideoFrame(encoded->GetData(),encoded->GetLength());

		//Set buffer size
		frame.SetMediaSize(encoded->GetLength());

		//Check type
		if (encoded->IsIntra())
			//Set type
			frame.SetFrameType(RTMPVideoFrame::INTRA);
		else
			//Set type
			frame.SetFrameType(RTMPVideoFrame::INTER);

	
		//If we need desc but yet not have it
		if (!frameDesc && encoded->IsIntra() && videoCodec==VideoCodec::H264)
		{
			//Create new description
			AVCDescriptor desc;
			//Set values
			desc.SetConfigurationVersion(1);
			desc.SetAVCProfileIndication(0x42);
			desc.SetProfileCompatibility(0x80);
			desc.SetAVCLevelIndication(0x0C);
			desc.SetNALUnitLength(3);
			//Get encoded data
			BYTE *data = encoded->GetData();
			//Get size
			DWORD size = encoded->GetLength();
			//get from frame
			desc.AddParametersFromFrame(data,size);
			//Crete desc frame
			frameDesc = new RTMPVideoFrame(getDifTime(&first)/1000,desc);
			//Lock
			pthread_mutex_lock(&mutex);
			//Send it
			SendMediaFrame(frameDesc);
			//unlock
			pthread_mutex_unlock(&mutex);
		}
		
		//Lock
		pthread_mutex_lock(&mutex);
		//Set timestamp
		frame.SetTimestamp(encoded->GetTimeStamp());
		//Publish it
		SendMediaFrame(&frame);
		//For each listener
		for(MediaFrameListeners::iterator it = mediaListeners.begin(); it!=mediaListeners.end(); ++it)
			//Send it
			(*it)->onMediaFrame(RTMPMediaStream::id,*encoded);
		//unlock
		pthread_mutex_unlock(&mutex);
	}
	Log("-FLVEncoder encode video end of loop\n");

	//Stop the capture
	videoInput->StopVideoCapture();

	//Check
	if (encoder)
		//Exit
		delete(encoder);
	Log("<FLVEncoder encode vide\n");
	
	//Exit
	return 1;
}
Esempio n. 3
0
AVCDescriptor* MP4Streamer::GetAVCDescriptor()
{
	uint8_t **sequenceHeader;
	uint8_t **pictureHeader;
	uint32_t *pictureHeaderSize;
	uint32_t *sequenceHeaderSize;
	uint32_t i;
	uint8_t profile, level;
	uint32_t len;
	
	//Check video
	if (!video || video->codec!=VideoCodec::H264)
		//Nothing
		return NULL;

	//Create descriptor
	AVCDescriptor* desc = new AVCDescriptor();

	//Set them
	desc->SetConfigurationVersion(0x01);
	desc->SetAVCProfileIndication(profile);
	desc->SetProfileCompatibility(0x00);
	desc->SetAVCLevelIndication(level);

	//Set nalu length
	MP4GetTrackH264LengthSize(video->mp4, video->track, &len);

	//Set it
	desc->SetNALUnitLength(len-1);

	// Get SEI informaMP4GetTrackH264SeqPictHeaderstion
	MP4GetTrackH264SeqPictHeaders(video->mp4, video->track, &sequenceHeader, &sequenceHeaderSize, &pictureHeader, &pictureHeaderSize);

	// Send sequence headers
	i=0;

	// Check we have sequence header
	if (sequenceHeader)
	{
		// Loop array
		while(sequenceHeader[i] && sequenceHeaderSize[i])
		{
			//Append sequence
			desc->AddSequenceParameterSet(sequenceHeader[i],sequenceHeaderSize[i]);
			//Update values based on the ones in SQS
			desc->SetAVCProfileIndication(sequenceHeader[i][1]);
			desc->SetProfileCompatibility(sequenceHeader[i][2]);
			desc->SetAVCLevelIndication(sequenceHeader[i][3]);
			//inc
			i++;
		}
	}

	// Send picture headers
	i=0;

	// Check we have picture header
	if (pictureHeader)
	{
		// Loop array
		while(pictureHeader[i] && pictureHeaderSize[i])
		{
			//Append sequence
			desc->AddPictureParameterSet(pictureHeader[i],pictureHeaderSize[i]);
			//inc
			i++;
		}
	}

	// Free data
	if (pictureHeader)
		free(pictureHeader);
	if (sequenceHeader)
		free(sequenceHeader);
	if (sequenceHeaderSize)
		free(sequenceHeaderSize);
	if (pictureHeaderSize)
		free(pictureHeaderSize);

	return desc;
}