Example #1
0
 void CameraBuffer::execute(DataProvider& provider)
 {
     // get the input data
     Id2DataPair inputMapper(INPUT);
     provider.receiveInputData(inputMapper);
     
     // try to get a free buffer
     Data* buffer = 0;
     try
     {
         buffer = m_buffers(0);
     }
     catch(Timeout&)
     {
     }
     
     if(buffer)
     {
         // there was a free buffer
         DataContainer bufferContainer(buffer);
         
         // remember it in the recycling access
         m_buffers.add(bufferContainer);
         
         Id2DataPair outputMapper(OUTPUT, inputMapper.data());
         Id2DataPair bufferMapper(BUFFER, bufferContainer);
         Id2DataPair idMapper(INDEX, DataContainer(new UInt32(m_id)));
         
         // send it to the output (together with the input image and the current index)
         provider.sendOutputData(outputMapper && bufferMapper && idMapper);
     }
     
     // increase the index
     ++m_id;
 }
bool SendFileHandler(int socket, int commandLength)
{
	qDebug()<<"Recieved send file command";

	const int bufferSize = 500 * 1024;
	char* buffer = new char[bufferSize];
	boost::scoped_array<char> bufferContainer(buffer);

	unsigned long transferId;
	if(!getFourByte(socket, transferId))
	{
		qDebug()<<"Get transfer id error";
		return false;
	}

	commandLength -= 4;
	if(!receiveData(socket, buffer, commandLength))
	{
		qDebug()<<"Receive file name error";
		return false;
	}
	buffer[commandLength] = 0;
	ReceiveFile receiveFile(buffer, transferId);
	receiveFile.doCommand();

	return true;
}
void DataChannel::run()
{
	int transferId;
	if(!receiveData(m_Socket, (char*)&transferId, sizeof(transferId)))
	{
		emit errorHappend(ReceiveDataError);
		return;
	}
	transferId = ntohl(transferId);

	DataServerThread* dataServer = DataServerThread::createDataServer();

	DataTransfer* dataTransfer;
	try{
		dataTransfer = dataServer->getAndPopTransfer(transferId);
	}catch(...)
	{
		qDebug()<<tr("无法找到对应的传送数据ID");
		return;
	}

	unsigned long fileStatusCode; //客户端的文件是否存在等信息
	if(!getFourByte(m_Socket, fileStatusCode))
	{
		qDebug()<<tr("得到远程文件信息出错");
		return;
	}

	unsigned long responseCode = 0;
	if(fileStatusCode == 0x1) //文件已经存在
	{

		if(Parameters::transferExistsFileHandleCode == 0) //需要询问
		{
			dataTransfer->setSomethingHappended(fileStatusCode); //通过GUI询问是否继续覆盖
			dataTransfer->waitFor();
			responseCode = dataTransfer->getResponseCode();
		}
		else if(Parameters::transferExistsFileHandleCode == 1) //覆盖
		{
			//不处理
			responseCode = 1;
		}
		else if(Parameters::transferExistsFileHandleCode == 2) //跳过
		{
			responseCode = 2;
			dataTransfer->setCancelled();
		}
		else if(Parameters::transferExistsFileHandleCode == 3) //续传
		{
			responseCode = 3;
		}
	}

	unsigned long tmpResponseCode = responseCode;

	if(!sendData(m_Socket, FBtoNetworkCharP(responseCode), sizeof(responseCode)))
	{
		qDebug()<<tr("回传是否覆盖文件代码出错!");
		return;
	}

	if(tmpResponseCode == 3)//续传需要接受已有文件大小
	{
		unsigned long lowPart,highPart;
		if(!getFourByte(m_Socket, lowPart))
		{
			qDebug()<<tr("得到已有文件的大小的低字节部分出错!");
			return;
		}
		if(!getFourByte(m_Socket, highPart))
		{
			qDebug()<<tr("得到已有文件的大小的高字节部分出错!");
			return;
		}

		long long fileExistsSize = lowPart | ( (long long)highPart << 32);

		dataTransfer->setPointer(fileExistsSize);
	}

	if(dataTransfer->isCancelled())
	{
		return;
	}

	dataTransfer->setSomethingHappended(0x00); // 发送传送文件已经开始的信号

	const unsigned long bufferSize = 20000;
	char* buffer = new char[bufferSize];
	boost::scoped_array<char> bufferContainer(buffer);

	long long dataSize = dataTransfer->dataSize();
	long long sendedSize = dataTransfer->getSendedSize(); //如果是续传这个值不会为0
	long long remainedSize = dataSize - sendedSize;
	while(sendedSize < dataSize)
	{
		if(dataTransfer->isCancelled())
		{
			break;
		}

		long long oneTimeSize = remainedSize < bufferSize ? remainedSize : bufferSize;
		long long readedSize = dataTransfer->readData(buffer, oneTimeSize);

		if(!sendData(m_Socket, buffer, readedSize))
		{
			dataTransfer->setFailed();
			emit errorHappend(SendDataError);
			return ;
		}
		sendedSize += readedSize;
		remainedSize -= readedSize;

		dataTransfer->setSendedSize(sendedSize);
	}
	closesocket(m_Socket);

}
void RegisterRequest::doRequest()
{
	unsigned long code = Register;
	if(!sendData(m_Socket, FBtoNetworkCharP(code), sizeof(code)))
	{
		setStatus(Failed);
		return;
	}

	//以下的代码为得到局域网的IP并发送给服务器
	struct sockaddr_in localAddress;
	int localAddressSize = sizeof(localAddress);
	if( getsockname(m_Socket, (SA*)&localAddress, &localAddressSize) == SOCKET_ERROR)
	{
		qDebug()<<"Get local address error";
		setStatus(Failed);
		return;
	}

	if(!sendData(m_Socket, reinterpret_cast<char*>(&localAddress.sin_addr.s_addr), 4))
	{
		qDebug()<<"Send local ip address error";
		setStatus(Failed);
		return;
	}

	unsigned short fileServerPort = htons(g_GroupFileServerPort);
	if(!sendData(m_Socket, reinterpret_cast<char*>(&fileServerPort), sizeof(fileServerPort)))
	{
		qDebug()<<"Send group file server port error";
		setStatus(Failed);
		return;
	}

	RealTimeServerThread* realTimeServerThread = RealTimeServerThread::instance();
	unsigned short videoServerPort = htons(realTimeServerThread->getVideoPort());
	if (!sendData(m_Socket, reinterpret_cast<char*>(&videoServerPort), sizeof(videoServerPort)))
	{
		qDebug()<<"Send video server port error";
		setStatus(Failed);
		return;
	}

	unsigned short audioServerPort = htons(realTimeServerThread->getAudioPort());
	if (!sendData(m_Socket, reinterpret_cast<char*>(&audioServerPort), sizeof(audioServerPort)))
	{
		qDebug()<<"Send audio server port error";
		setStatus(Failed);
		return;
	}

	unsigned long returnCode;
	if(!getFourByte(m_Socket, returnCode))
	{
		setStatus(Failed);
		return ;
	}

	if(returnCode == 0)
	{
		unsigned long xmlInfoLength;
		if(!getFourByte(m_Socket, xmlInfoLength))
		{
			setStatus(Failed);
			return ;
		}

		char* buffer = new char[xmlInfoLength];
		boost::scoped_array<char> bufferContainer(buffer);

		if(!receiveData(m_Socket, buffer, xmlInfoLength))
		{
			setStatus(Failed);
			return;
		}

		QDomDocument domDocument;
		if(!domDocument.setContent( QByteArray(buffer, xmlInfoLength), false))
		{
			setStatus(Failed);
			return;
		}

		QFile clientInfoXmlFile(g_InformationFileName);
		if(!clientInfoXmlFile.open(QFile::WriteOnly))
		{
			setStatus(Failed);
			return;
		}

		QTextStream stream(&clientInfoXmlFile);
		domDocument.save(stream, 4);

		qDebug()<<buffer;
		setStatus(Successful);
		return;
	}
	else
	{
		setStatus(Refused);
		return;
	}
}
DWORD WINAPI UdpReceiveThread(LPVOID param)
{
	HRESULT hr;
	ReceiveParam *receiveParam = (ReceiveParam*)param;
	HANDLE PushSemaphore = receiveParam->PushSemaphore;
	HANDLE PushDataMutex = receiveParam->PushDataMutex;
	std::map<REFERENCE_TIME,IMediaSample*>& SampleList = *receiveParam->SampleList;
	NetReceiveFilter* filter = receiveParam->filter;
	delete receiveParam;

	NetReceiveOutputPin* outputPin = reinterpret_cast<NetReceiveOutputPin*>(filter->GetPin(0));
	assert(outputPin != NULL);

	AM_MEDIA_TYPE mediaType;
	while (true)
	{
		outputPin->ConnectionMediaType(&mediaType);
		if (mediaType.majortype == GUID_NULL)
		{
			Sleep(300);
		}
		else
			break;
	}

	SOCKET udpSocket;
	udpSocket = ::socket(AF_INET, SOCK_DGRAM, 0);
	if (udpSocket == INVALID_SOCKET)
	{
		ErrorPrint("Create udp socket error");
		return 1;
	}

	sockaddr_in bindAddress;
	bindAddress.sin_family = AF_INET;
	bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
	if(mediaType.majortype == MEDIATYPE_Video)
	{
		bindAddress.sin_port = htons(VideoBroadcastPort);
	}
	else
	{
		bindAddress.sin_port = htons(AudioBroadcastPort);
	}

	int option = 1;
	int ret = setsockopt(udpSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&option, sizeof(option));
	if (ret == SOCKET_ERROR)
	{
		ErrorPrint("Set socket reuse address error");
		return 1;
	}

	int recvSystemBufferSize = 1024 * 1024 * 10;

	ret = setsockopt(udpSocket, SOL_SOCKET, SO_RCVBUF, (char*)&recvSystemBufferSize, sizeof(recvSystemBufferSize));
	if (ret == SOCKET_ERROR)
	{
		ErrorPrint("Set socket receive system buffer size error");
	}

	ret = ::bind(udpSocket, (sockaddr*)&bindAddress, sizeof(bindAddress));
	if(ret == SOCKET_ERROR)
	{
		ErrorPrint("Bind udp receive socket error");
		return 1;
	}

	sockaddr_in fromAddress;
	fromAddress.sin_family = AF_INET;
	int addressLen = sizeof(fromAddress);

	std::map<long long, IMediaSample*> idToSampleMap;

	const int packetMaxSize = 10 * 1024;
	MediaPacketHeader* mediaPacketHeader = (MediaPacketHeader*)new char[sizeof(MediaPacketHeader) + packetMaxSize];
	boost::scoped_array<char> bufferContainer((char*)mediaPacketHeader);
	char* dataStart = (char*)mediaPacketHeader;
	char* dataBuffer = (char*)mediaPacketHeader + sizeof(MediaPacketHeader);
	while (true)
	{
		int recvedSize = recvfrom(udpSocket, dataStart, sizeof(MediaPacketHeader) + packetMaxSize, 0, (sockaddr*)&fromAddress, &addressLen);
		if (recvedSize == SOCKET_ERROR)
		{
			ErrorPrint("Receive from udp error");
			return 1;
		}

		if (g_IsBroadcasting) //是自己广播的数据包,丢弃之
		{
			continue;
		}

		if (mediaPacketHeader->type == 0) // 是sample头
		{
#ifdef UDP_PRINT
			std::cout<<"Receive media packet header:"<<mediaPacketHeader->id<<std::endl;
#endif
			std::map<long long, IMediaSample*>::iterator it = idToSampleMap.begin();
			while (it != idToSampleMap.end()) //处理发生过丢包的sample
			{
				std::map<long long, IMediaSample*>::iterator tmp = it++;
				if (tmp->first < mediaPacketHeader->id) //这个sample肯定丢包了,序列号比后来的小,并且没有接受完整,直接丢弃掉
				{
					std::cout<<"Lose packet:"<<mediaPacketHeader->id<<std::endl;
					tmp->second->Release(); //一定要把sample给释放掉
					idToSampleMap.erase(tmp);
				}
				else //将所有要丢弃的包都处理完了
					break;
			}

// 			if (mediaType.majortype == MEDIATYPE_Video)
// 			{
// 				std::cout<<"Video header:"<<mediaPacketHeader->id<<std::endl;
// 			}

//			std::cout<<"Before get free sample"<<std::endl;
			IMediaSample *sample = filter->GetFreeSample(); //此时为这个sample头申请一个新的sample
//			std::cout<<"After get free sample"<<std::endl;
			if (sample == NULL)
			{
				ErrorPrint("Get free sample error");
				return 1;
			}

			AM_SAMPLE2_PROPERTIES* sample2Properties = (AM_SAMPLE2_PROPERTIES*)dataBuffer;

			sample2Properties->cbData = sizeof(AM_SAMPLE2_PROPERTIES) - 9;

			IMediaSample2 *mediaSample2;
			hr = sample->QueryInterface(IID_IMediaSample2, (void**)&mediaSample2);
			if (FAILED(hr))
			{
				ErrorPrint("Get media sample2 interface error",hr);
				sample->Release();
				return 1;
			}
			ComReleaser mediaSample2Releaser(mediaSample2);

			hr = mediaSample2->SetProperties(sample2Properties->cbData, (BYTE*)sample2Properties);//设置sample属性
			if (FAILED(hr))
			{
				ErrorPrint("Set sample properties error");
			}
			sample->SetTime(&(sample2Properties->tStart), &(sample2Properties->tStop));
			sample->SetActualDataLength(sample2Properties->lActual);

			idToSampleMap.insert(std::make_pair(mediaPacketHeader->id, sample)); //插入到map当中,等待所有的sample数据接受完
		}
		else if (mediaPacketHeader->type == 1) //是sample数据
		{
#ifdef UDP_PRINT
			std::cout<<"Receive sample data:"<<mediaPacketHeader->id<<std::endl;
#endif
			std::map<long long, IMediaSample*>::iterator it = idToSampleMap.find(mediaPacketHeader->id);
			if (it != idToSampleMap.end()) //如果id找不到,sample头丢失了,或者已经过期了,直接将该包丢弃
			{
				IMediaSample* sample = it->second;
				PBYTE dataPointer = NULL;
				hr = sample->GetPointer(&dataPointer);
				if (FAILED(hr))
				{
					ErrorPrint("Get data pointer error",hr);
					idToSampleMap.erase(it);
					sample->Release();
					continue;
				}
				memcpy(dataPointer + mediaPacketHeader->offset, dataBuffer, mediaPacketHeader->size);
				if ( (mediaPacketHeader->offset + mediaPacketHeader->size) == sample->GetActualDataLength()) //已经接收完整了,当然也有可能中间数据丢包了,但现在不管这种情况
				{
					idToSampleMap.erase(it);
					REFERENCE_TIME startTime,endTime;
					sample->GetTime(&startTime,&endTime);
					//通知PUSH线程进行数据传送
					WaitForSingleObject(PushDataMutex, INFINITE);
// 					if (mediaType.majortype == MEDIATYPE_Video)
// 					{
// 						std::cout<<"Finished Video sample:"<<mediaPacketHeader->id<<";Current Thread:"<<GetCurrentThreadId()<<";Map size:"<<idToSampleMap.size()<<std::endl;
// 						std::cout<<"Sample start time:"<<startTime <<";Sample end time:"<<endTime<<std::endl;
// 					}
					SampleList.insert(std::make_pair(startTime,sample));
					if (SampleList.size() >= 24 * 10)
					{
						ReleaseSemaphore(PushSemaphore, 1, NULL);
					}
					ReleaseMutex(PushDataMutex);
				}
			}
			else
				std::cout<<"Lose packet header:"<<mediaPacketHeader->id<<std::endl;
		}

// 		if(idToSampleMap.size() == 0 ||  idToSampleMap.begin()->first < )
// 
// 		mediaPacketHeader
// 

	}
}