コード例 #1
0
ファイル: TSSrcFilter.cpp プロジェクト: HK323232/EDCB
DWORD CTSSrcFilter::AddTS(BYTE* data, DWORD size)
{
	DWORD addVideo = 0;
	for( DWORD i=0; i<size; i+=188 ){
		CTSPacketUtil packet;
		if( packet.Set188TS(data + i, 188) == TRUE ){
			if( packet.transport_scrambling_control == 0 ){
				//PMT
				map<WORD, CPMTUtil*>::iterator itrPmt;
				if( packet.payload_unit_start_indicator == 1 && packet.data_byteSize > 0){
					BYTE pointer = packet.data_byte[0];
					if( pointer+1 < packet.data_byteSize ){
						if( packet.data_byte[1+pointer] == 0x02 ){
							//PMT
							map<WORD, CPMTUtil*>::iterator itrPmt;
							itrPmt = this->pmtUtilMap.find(packet.PID);
							if( itrPmt == this->pmtUtilMap.end() ){
								CPMTUtil* util = new CPMTUtil;
								this->pmtUtilMap.insert(pair<WORD, CPMTUtil*>(packet.PID, util));
								if( util->AddPacket(&packet) == TRUE ){
									CheckPID();
								}
							}else{
								if( itrPmt->second->AddPacket(&packet) == TRUE ){
									CheckPID();
								}
							}
						}
					}
				}else{
					//PMTの2パケット目かチェック
					map<WORD, CPMTUtil*>::iterator itrPmt;
					itrPmt = this->pmtUtilMap.find(packet.PID);
					if( itrPmt != this->pmtUtilMap.end() ){
						if( itrPmt->second->AddPacket(&packet) == TRUE ){
							CheckPID();
						}
					}
				}
				if( packet.PID == videoPID ){
					videoBuff.Add188TS(&packet);
					BYTE* buff = NULL;
					DWORD buffSize = 0;
					BOOL ret = videoBuff.GetSectionBuff(&buff, &buffSize);
					if( ret == TRUE ){
						CPESHeadInfo info;
						info.SetData(buff, buffSize);
						LONGLONG pts = 0;
						LONGLONG time = 0;
						if( info.PTS_DTS_flags == 3 ){
							if(this->startTSV == 0){
								this->startTSV = info.DTS;
							}
							if( this->startTS == 0 ){
								this->startTS = this->startTSV;
							}
							pts = info.DTS;
						}else if( info.PTS_DTS_flags == 2 ){
							if(this->startTSV == 0){
								this->startTSV = info.PTS;
							}
							if( this->startTS == 0 ){
								this->startTS = this->startTSV;
							}
							pts = info.PTS;
						}
						if( this->startTSV > pts ){
							pts += 0x1FFFFFFFF;
						}
						time = ((pts-this->startTS)/90)*10000;
						if( info.PES_packet_data_byte_size > 0 && time >= 0){
							this->m_pVideoPin->AddData(info.PES_packet_data_byte, info.PES_packet_data_byte_size, time);
							addVideo++;
						}
					}
				}else if( packet.PID == audioPID ){
					audioBuff.Add188TS(&packet);
					BYTE* buff = NULL;
					DWORD buffSize = 0;
					BOOL ret = audioBuff.GetSectionBuff(&buff, &buffSize);
					if( ret == TRUE ){
						CPESHeadInfo info;
						info.SetData(buff, buffSize);
						LONGLONG pts = 0;
						LONGLONG time = 0;
						if( info.PTS_DTS_flags == 3 ){
							if(this->startTSA == 0){
								this->startTSA = info.DTS;
							}
							if( this->startTS == 0 ){
								this->startTS = this->startTSV;
							}
							pts = info.DTS;
						}else if( info.PTS_DTS_flags == 2 ){
							if(this->startTSA == 0){
								this->startTSA = info.PTS;
							}
							if( this->startTS == 0 ){
								this->startTS = this->startTSV;
							}
							pts = info.PTS;
						}
						if( this->startTSA > pts ){
							pts += 0x1FFFFFFFF;
						}
						time = ((pts-this->startTS)/90)*10000;
						if( info.PES_packet_data_byte_size > 0 && time >= 0){
							this->m_pAudioPin->AddData(info.PES_packet_data_byte, info.PES_packet_data_byte_size, time);
						}
					}
				}
			}
		}
	}
	return addVideo;
}
コード例 #2
0
ファイル: TimeShiftUtil.cpp プロジェクト: nekopanda/EDCB
UINT WINAPI CTimeShiftUtil::ReadThread(LPVOID param)
{
	CoInitialize(NULL);
	CTimeShiftUtil* sys = (CTimeShiftUtil*)param;
	BYTE buff[188*256];
	CPacketInit packetInit;

	HANDLE file = CreateFile( sys->filePath.c_str(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	if( file == INVALID_HANDLE_VALUE ){
		return FALSE;
	}

	DWORD lenH = 0;
	DWORD lenL = GetFileSize(file, &lenH);
	__int64 totlaFileSize = ((__int64)lenH)<<32 | lenL;
	if( totlaFileSize < sys->currentFilePos ){
		sys->currentFilePos = totlaFileSize;
	}
	sys->totalFileSize = totlaFileSize;

	LONG setH = (LONG)(sys->currentFilePos>>32);
	LONG setL = (LONG)(sys->currentFilePos & 0x00000000FFFFFFFF);
	SetFilePointer(file, setL, &setH, FILE_BEGIN);

	__int64 initTime = -1;
	__int64 initTick = 0;

	DWORD errCount = 0;
	__int64 pcr_offset = 0;
	__int64 tick_offset = 0;

	for(;;){
		if( ::WaitForSingleObject(sys->readStopEvent, 0) != WAIT_TIMEOUT ){
			//キャンセルされた
			break;
		}
		__int64 totalReadSize = sys->currentFilePos;
		DWORD readSize = 0;
		DWORD buffSize = 188*256;
		if( sys->availableFileSize != -1 && sys->fileMode == FALSE ){
			if( totalReadSize + buffSize > sys->availableFileSize ){
				buffSize = (DWORD)(sys->availableFileSize-totalReadSize);
			}
		}
		if( totalReadSize + buffSize > sys->totalFileSize && sys->fileMode == FALSE){
			//ファイルサイズ変わっていってるはずなので開き直す
			CloseHandle(file);
			file = CreateFile( sys->filePath.c_str(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
			if( file == INVALID_HANDLE_VALUE ){
				return FALSE;
			}
			setH = (LONG)(sys->currentFilePos>>32);
			setL = (LONG)(sys->currentFilePos & 0x00000000FFFFFFFF);
			SetFilePointer(file, setL, &setH, FILE_BEGIN);

			lenH = 0;
			lenL = GetFileSize(file, &lenH);
			__int64 newSize = ((__int64)lenH)<<32 | lenL;

			sys->totalFileSize = newSize;
			Sleep(50);
			errCount++;
			if( errCount > (1000/50)*10){
				//10秒間ファイルサイズの更新ないから終端のはず
				CloseHandle(file);
				return FALSE;
			}
			continue;
		}
		BOOL ret = ReadFile( file, buff, buffSize, &readSize, NULL );
		if( ret == FALSE || readSize < buffSize){
			if( sys->fileMode == TRUE ){
				//ファイルモードだからエラーは終端のはず
				CloseHandle(file);
				return FALSE;
			}else{
				Sleep(50);
				errCount++;
				if( errCount > (1000/50)*10){
					//10秒間ファイルサイズの更新ないから終端のはず
					CloseHandle(file);
					return FALSE;
				}
			}
		}else{
			errCount = 0;
		}
		if( readSize == 0 ){
			Sleep(50);
			continue;
		}
		BYTE* data = NULL;
		DWORD dataSize = 0;
		__int64 base = -1;
		if( packetInit.GetTSData(buff, readSize, &data, &dataSize) == TRUE ){
			if( sys->LockBuff() == TRUE ){
				for( DWORD i=0; i<dataSize; i+=188 ){
					CTSPacketUtil packet;
					if( packet.Set188TS(data + i, 188) == TRUE ){
						if( packet.transport_scrambling_control == 0 ){
							//PMT
							if( packet.payload_unit_start_indicator == 1 && packet.data_byteSize > 0){
								BYTE pointer = packet.data_byte[0];
								if( pointer+1 < packet.data_byteSize ){
									if( packet.data_byte[1+pointer] == 0x02 ){
										//PMT
										map<WORD, CPMTUtil*>::iterator itrPmt;
										itrPmt = sys->pmtUtilMap.find(packet.PID);
										if( itrPmt == sys->pmtUtilMap.end() ){
											CPMTUtil* util = new CPMTUtil;
											sys->pmtUtilMap.insert(pair<WORD, CPMTUtil*>(packet.PID, util));
											if( util->AddPacket(&packet) == TRUE ){
												if( sys->PCR_PID != util->PCR_PID ){
													//チャンネル変わった?
													initTime = -1;
													initTick = 0;
												}
												sys->PCR_PID = util->PCR_PID;
											}
										}else{
											if( itrPmt->second->AddPacket(&packet) == TRUE ){
												if( sys->PCR_PID != itrPmt->second->PCR_PID ){
													//チャンネル変わった?
													initTime = -1;
													initTick = 0;
												}
												sys->PCR_PID = itrPmt->second->PCR_PID;
											}
										}
									}
								}
							}else{
								//PMTの2パケット目かチェック
								map<WORD, CPMTUtil*>::iterator itrPmt;
								itrPmt = sys->pmtUtilMap.find(packet.PID);
								if( itrPmt != sys->pmtUtilMap.end() ){
									if( itrPmt->second->AddPacket(&packet) == TRUE ){
										if( sys->PCR_PID != itrPmt->second->PCR_PID ){
											//チャンネル変わった?
											initTime = -1;
											initTick = 0;
										}
										sys->PCR_PID = itrPmt->second->PCR_PID;
									}
								}
							}

							if( packet.adaptation_field_length > 0 && packet.PCR_flag == 1 ){
								if( sys->PCR_PID == 0xFFFF ){
									//最初に捕まえたPCRを暫定的に使う
									initTime = -1;
									sys->PCR_PID = packet.PID;
								}
								if( sys->PCR_PID == packet.PID ){
									base = (__int64)packet.program_clock_reference_base/90;
									if( initTime == -1 ){
										initTime = base;
										initTick = GetTickCount();
									}
								}
							}
						}
					}
				}
				sys->UnLockBuff();

				if( sys->sendUdp != NULL ){
					sys->sendUdp->SendData(data, dataSize);
				}
				if( sys->sendTcp != NULL ){
					sys->sendTcp->SendData(data, dataSize);
				}
			}
			sys->currentFilePos += readSize;
		}
		

		for(;;){
			if( initTime != -1 && base != -1){
				if( base+pcr_offset<initTime ){
					//PCR巻き戻った?
					pcr_offset = 0x1FFFFFFFF;
				}
				__int64 tick = GetTickCount();
				if( tick+tick_offset<initTick ){
					tick_offset = 0xFFFFFFFF;
				}
				if( (base+pcr_offset)-initTime >tick+tick_offset-initTick+100){
					if( ::WaitForSingleObject(sys->readStopEvent, 20) != WAIT_TIMEOUT ){
						//キャンセルされた
						goto Err_End;
					}
				}else{
					break;
				}
			}else{
				break;
			}
		}
	}