diff --git a/BonCtrl/TSOut.cpp b/BonCtrl/TSOut.cpp
index f3055de..56b4c99 100644
--- a/BonCtrl/TSOut.cpp
+++ b/BonCtrl/TSOut.cpp
@@ -72,14 +72,14 @@ BOOL CTSOut::Lock(LPCWSTR log, DWORD timeOut)
 	//	OutputDebugString(log);
 	//}
 	DWORD dwRet = WaitForSingleObject(this->lockEvent, timeOut);
-	if( dwRet == WAIT_ABANDONED || 
-		dwRet == WAIT_FAILED ||
-		dwRet == WAIT_TIMEOUT){
-			if( log != NULL ){
-				_OutputDebugString(L"◆CTSOut::Lock FALSE : %s", log);
-			}else{
-				OutputDebugString(L"◆CTSOut::Lock FALSE");
-			}
+	if( dwRet == WAIT_ABANDONED ||
+	    dwRet == WAIT_FAILED ||
+	    dwRet == WAIT_TIMEOUT){
+		if( log != NULL ){
+			_OutputDebugString(L"◆CTSOut::Lock FALSE : %s", log);
+		}else{
+			OutputDebugString(L"◆CTSOut::Lock FALSE");
+		}
 		return FALSE;
 	}
 	return TRUE;
@@ -99,45 +99,55 @@ DWORD CTSOut::SetChChangeEvent(BOOL resetEpgUtil)
 {
 	if( Lock(L"SetChChangeEvent") == FALSE ) return ERR_FALSE;
 
-	this->chChangeFlag = TRUE;
-	this->chChangeErr = FALSE;
-	this->chChangeTime = GetTimeCount();
+	try {
+		this->chChangeFlag = TRUE;
+		this->chChangeErr = FALSE;
+		this->chChangeTime = GetTimeCount();
 
-	this->decodeUtil.UnLoadDll();
+		this->decodeUtil.UnLoadDll();
 
-	SAFE_DELETE(this->catUtil);
+		SAFE_DELETE(this->catUtil);
 
-	if( resetEpgUtil == TRUE ){
-		this->epgUtil.UnInitialize();
-		this->epgUtil.Initialize(FALSE);
-	}
+		if( resetEpgUtil == TRUE ){
+			this->epgUtil.UnInitialize();
+			this->epgUtil.Initialize(FALSE);
+		}
 
-	UnLock();
-	return NO_ERR;
+		UnLock();
+		return NO_ERR;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 BOOL CTSOut::IsChChanging(BOOL* chChgErr)
 {
 	if( Lock(L"IsChChanging") == FALSE ) return ERR_FALSE;
 
-	BOOL ret = this->chChangeFlag;
-	if( chChgErr != NULL ){
-		*chChgErr = this->chChangeErr;
-	}
+	try {
+		BOOL ret = this->chChangeFlag;
+		if( chChgErr != NULL ){
+			*chChgErr = this->chChangeErr;
+		}
 
-	if( this->chChangeTime == 0 ){
-		this->chChangeTime = GetTimeCount();
-	}else if( GetTimeCount() > this->chChangeTime + 15 ){
-		ret = FALSE;
-		if( this->chChangeFlag == TRUE ){
-			if( chChgErr != NULL ){
-				*chChgErr = TRUE;
+		if( this->chChangeTime == 0 ){
+			this->chChangeTime = GetTimeCount();
+		}else if( GetTimeCount() > this->chChangeTime + 15 ){
+			ret = FALSE;
+			if( this->chChangeFlag == TRUE ){
+				if( chChgErr != NULL ){
+					*chChgErr = TRUE;
+				}
 			}
 		}
-	}
 
-	UnLock();
-	return ret;
+		UnLock();
+		return ret;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 void CTSOut::ResetChChange()
@@ -150,18 +160,69 @@ BOOL CTSOut::GetStreamID(WORD* ONID, WORD* TSID)
 {
 	if( Lock(L"GetStreamID") == FALSE ) return ERR_FALSE;
 
-	BOOL ret = TRUE;
-	if( this->chChangeFlag == TRUE ){
-		ret = FALSE;
-	}else{
-		ret = this->epgUtil.GetTSID(ONID, TSID);
-		if( ret == NO_ERR ){
-			this->lastONID = *ONID;
-			this->lastTSID = *TSID;
+	try {
+		BOOL ret = TRUE;
+		if( this->chChangeFlag == TRUE ){
+			ret = FALSE;
+		}else{
+			ret = this->epgUtil.GetTSID(ONID, TSID);
+			if( ret == NO_ERR ){
+				this->lastONID = *ONID;
+				this->lastTSID = *TSID;
+			}
 		}
+		UnLock();
+		return ret;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
 	}
-	UnLock();
-	return ret;
+}
+
+BOOL CTSOut::CheckChChangeCompletion(WORD onid, WORD tsid) const
+{
+	if ((onid != this->lastONID) || (tsid != this->lastTSID)) {
+		// 変更前 TS ID/Network ID から変化
+		OutputDebugString(L"★Ch Change Complete\r\n");
+		_OutputDebugString(L"★Ch 0x%04X 0x%04X => 0x%04X 0x%04X\r\n", this->lastONID, this->lastTSID, onid, tsid);
+		return TRUE;
+	}
+
+	if (GetTimeCount() > (this->chChangeTime + 7)) {
+		// チャンネル変更開始から 7 秒経過 - これを本当に成功扱いにしてよいのだろうか
+		OutputDebugString(L"★Ch NoChange\r\n");
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void CTSOut::OnChChanged(WORD onid, WORD tsid)
+{
+	this->chChangeFlag = FALSE;
+	this->chChangeErr = FALSE;
+	this->lastONID = onid;
+	this->lastTSID = tsid;
+	this->epgUtil.ClearSectionStatus();
+
+	if ((this->enableDecodeFlag != FALSE) ||
+	    (this->emmEnableFlag != FALSE)) {
+		// CScrambleDecoderUtil::SetNetwork() はロードする DLL を
+		// ネットワーク ID と TS ID を元に切り替えて読み込む
+		// スクランブル解除かEMM処理が設定されている場合だけ実行
+		if (this->decodeUtil.SetNetwork(onid, tsid) == FALSE) {
+			OutputDebugString(L"★★Decode DLL load err [CTSOut::OnChChanged()]\r\n");
+			// 再試行は意味がなさそうなので廃止
+		}
+		this->decodeUtil.SetEmm(this->emmEnableFlag);
+	}
+	ResetErrCount();
+
+	map<WORD, CPMTUtil*>::iterator itrPmt;
+	for( itrPmt = this->pmtUtilMap.begin(); itrPmt != this->pmtUtilMap.end(); itrPmt++ ){
+		SAFE_DELETE(itrPmt->second);
+	}
+	this->pmtUtilMap.clear();
 }
 
 DWORD CTSOut::AddTSBuff(TS_DATA* data)
@@ -177,265 +238,187 @@ DWORD CTSOut::AddTSBuff(TS_DATA* data)
 	}
 	if( data->size > this->decodeBuffSize ){
 		SAFE_DELETE_ARRAY(this->decodeBuff);
-		this->decodeBuff = new BYTE[data->size*2];
-		this->decodeBuffSize = data->size*2;
+		// デッドロック暫定回避変更
+		try { 
+			this->decodeBuff = new BYTE[data->size*2];
+			this->decodeBuffSize = data->size*2;
+		} catch (...){
+			this->decodeBuff = NULL;
+			this->decodeBuffSize = 0;
+			UnLock();
+			return ERR_FALSE;
+		}
 	}
 	this->deocdeBuffWriteSize = 0;
 
 	BYTE* decodeData = NULL;
 	DWORD decodeSize = 0;
-	BOOL chChgComp = FALSE;
 	try{
 		for( DWORD i=0; i<data->size; i+=188 ){
+
+			if ((data->size - i) < 188) {
+				// TS パケットサイズに足りない - 本来ここには来ないはず
+				OutputDebugString(L"[marumo:debug] CTSOut::AddTSBuff() / パケットサイズ不足\r\n");
+				continue;
+			}
+
 			CTSPacketUtil packet;
-			if( packet.Set188TS(data->data + i, 188) == TRUE ){
+			if( packet.Set188TS(data->data + i, 188) != TRUE ){
+				// パケットヘッダ解析に失敗したゴミパケット - 通常は無視する
 				if( this->chChangeFlag == TRUE ){
-					//チャンネル切り替え中
-					if(GetTimeCount() < this->chChangeTime + 1){
-						//1秒間は切り替え前のパケット来る可能性を考慮して無視する
-						UnLock();
-						return NO_ERR;
-					}
-					//簡易パケット解析
-					if( packet.transport_scrambling_control != 0 ){
-						//スクランブルパケットなので解析できない
-						continue;
-					}
-					if( packet.data_byteSize < 3 ){
-						//サイズが小さすぎる
-						continue;
-					}
-					if(packet.payload_unit_start_indicator == 1 && 
-						packet.data_byte[0] == 0x00 &&
-						packet.data_byte[1] == 0x00 &&
-						packet.data_byte[2] == 0x01){
-						//PES
-						continue;
-					}
-					try{
-						this->epgUtil.AddTSPacket(data->data + i, 188);
-					}catch(...){
-						_OutputDebugString(L"★★CTSOut::AddTSBuff epgUtil.AddTSPacket");
-						this->epgUtil.UnInitialize();
-						this->epgUtil.Initialize(FALSE);
+					// チャンネル切り替え中だけ特殊処理
+					if( GetTimeCount() > this->chChangeTime + 15 ){
+						//15秒以上たってるのにゴミパケットが届いた
+						OutputDebugString(L"★Ch Change Err NoPacket\r\n");
+						this->chChangeErr = TRUE;
+						this->lastONID = 0xFFFF;
+						this->lastTSID = 0xFFFF;
+						// 処理を打ち切ってエラーを返すべきでは？
+						// 正しいエラー処理方法が判らないのでオリジナルの処理を維持
 					}
-					WORD onid = 0xFFFF;
-					WORD tsid = 0xFFFF;
-					if( this->epgUtil.GetTSID(&onid, &tsid) == NO_ERR ){
-						if( onid != this->lastONID || tsid != this->lastTSID ){
-							OutputDebugString(L"★Ch Change Complete\r\n");
-						_OutputDebugString(L"★Ch 0x%04X 0x%04X => 0x%04X 0x%04X\r\n", this->lastONID, this->lastTSID, onid, tsid);
-							this->chChangeFlag = FALSE;
-							this->chChangeErr = FALSE;
-							this->lastONID = onid;
-							this->lastTSID = tsid;
-							this->epgUtil.ClearSectionStatus();
-							if( this->decodeUtil.SetNetwork(onid, tsid) == FALSE ){
-								OutputDebugString(L"★★Decode DLL load err\r\n");
-								Sleep(100);
-								this->decodeUtil.SetNetwork(onid, tsid);
-							}
-							this->decodeUtil.SetEmm(this->emmEnableFlag);
-							ResetErrCount();
-							chChgComp = TRUE;
-
-							map<WORD, CPMTUtil*>::iterator itrPmt;
-							for( itrPmt = this->pmtUtilMap.begin(); itrPmt != this->pmtUtilMap.end(); itrPmt++ ){
-								SAFE_DELETE(itrPmt->second);
-							}
-							this->pmtUtilMap.clear();
-
-						}else if( this->lastONID == onid && this->lastTSID == tsid &&
-							(GetTimeCount() > this->chChangeTime + 7)
-							){
-							OutputDebugString(L"★Ch NoChange\r\n");
-								this->chChangeFlag = FALSE;
-								this->chChangeErr = FALSE;
-								this->lastONID = onid;
-								this->lastTSID = tsid;
-								this->epgUtil.ClearSectionStatus();
-								if( this->decodeUtil.SetNetwork(onid, tsid) == FALSE ){
-									OutputDebugString(L"★★Decode DLL load err\r\n");
-									Sleep(100);
-									this->decodeUtil.SetNetwork(onid, tsid);
-								}
-								this->decodeUtil.SetEmm(this->emmEnableFlag);
-								ResetErrCount();
-								chChgComp = TRUE;
+				}
+				continue;
+			}
 
-								map<WORD, CPMTUtil*>::iterator itrPmt;
-								for( itrPmt = this->pmtUtilMap.begin(); itrPmt != this->pmtUtilMap.end(); itrPmt++ ){
-									SAFE_DELETE(itrPmt->second);
-								}
-								this->pmtUtilMap.clear();
-						}else if( GetTimeCount() > this->chChangeTime + 15 ){
-							if( this->lastONID == onid && this->lastTSID == tsid ){
-								this->chChangeFlag = FALSE;
-								this->chChangeErr = FALSE;
-								this->lastONID = onid;
-								this->lastTSID = tsid;
-								this->epgUtil.ClearSectionStatus();
-								if( this->decodeUtil.SetNetwork(onid, tsid) == FALSE ){
-									OutputDebugString(L"★★Decode DLL load err\r\n");
-									Sleep(100);
-									this->decodeUtil.SetNetwork(onid, tsid);
-								}
-								this->decodeUtil.SetEmm(this->emmEnableFlag);
-								ResetErrCount();
-								chChgComp = TRUE;
+			if( this->chChangeFlag == TRUE ){
+				//チャンネル切り替え中
+				if(GetTimeCount() < this->chChangeTime + 1){
+					//1秒間は切り替え前のパケット来る可能性を考慮して無視する
+					UnLock();
+					return NO_ERR;
+				}
+				//簡易パケット解析
+				if( packet.transport_scrambling_control != 0 ){
+					//スクランブルパケットは解析対象外
+					continue;
+				}
+				if( packet.data_byteSize < 3 ){
+					//サイズが小さすぎる
+					continue;
+				}
+				if(packet.payload_unit_start_indicator == 1 &&
+				   packet.data_byte[0] == 0x00 &&
+				   packet.data_byte[1] == 0x00 &&
+				   packet.data_byte[2] == 0x01){
+					//PESパケットも解析対象外
+					continue;
+				}
+				try{
+					this->epgUtil.AddTSPacket(data->data + i, 188);
+				}catch(...){
+					_OutputDebugString(L"★★CTSOut::AddTSBuff epgUtil.AddTSPacket");
+					this->epgUtil.UnInitialize();
+					this->epgUtil.Initialize(FALSE);
+				}
+				WORD onid = 0xFFFF;
+				WORD tsid = 0xFFFF;
+				if( this->epgUtil.GetTSID(&onid, &tsid) != NO_ERR ){
+					// 解析パケットが不足していて TS ID および Network ID が特定できない場合にここに来る
+					// 通常は、そのまま次のパケットに進む
+					if( GetTimeCount() > this->chChangeTime + 15 ){
+						//チャンネル切り替え開始から 15 秒を超えた場合は特殊処理
+						OutputDebugString(L"★GetTSID Err\r\n");
+						this->chChangeErr = TRUE;
+						this->lastONID = onid;
+						this->lastTSID = tsid;
+						// 処理を打ち切ってエラーを返すべきでは？
+						// 正しいエラー処理方法が判らないのでオリジナルの処理を維持
+					}
+					continue;
+				}
 
-								map<WORD, CPMTUtil*>::iterator itrPmt;
-								for( itrPmt = this->pmtUtilMap.begin(); itrPmt != this->pmtUtilMap.end(); itrPmt++ ){
-									SAFE_DELETE(itrPmt->second);
-								}
-								this->pmtUtilMap.clear();
-							}else{
-//								OutputDebugString(L"★Ch Change Err\r\n");
-								//10秒以上たってるなら切り替わったとする
-								this->chChangeErr = TRUE;
-								//this->chChangeFlag = FALSE;
-								this->lastONID = onid;
-								this->lastTSID = tsid;
-							}
-							//this->epgUtil.ClearSectionStatus();
-							//this->decodeUtil.SetNetwork(onid, tsid);
-							//this->decodeUtil.SetEmm(this->emmEnableFlag);
-							//ResetErrCount();
+				if (CheckChChangeCompletion(onid, tsid) == FALSE) {
+					// チャンネル変更未完了
+					continue;
+				}
+				
+				// 正常系 - チャンネル切り替え成功
+				OnChChanged(onid, tsid);
+			}else{
+				//指定サービスに必要なPIDを解析
+				if( packet.transport_scrambling_control == 0 ){
+					//CAT
+					if( packet.PID == 0x0001 ){
+						if( this->catUtil == NULL ){
+							this->catUtil = new CCATUtil;
 						}
-					}
-					else{
-						if( GetTimeCount() > this->chChangeTime + 15 ){
-							//15秒以上たってるなら切り替わったとする
-							OutputDebugString(L"★GetTSID Err\r\n");
-							//this->chChangeFlag = FALSE;
-							this->chChangeErr = TRUE;
-							this->lastONID = onid;
-							this->lastTSID = tsid;
-							//this->epgUtil.ClearSectionStatus();
-							//this->decodeUtil.SetNetwork(onid, tsid);
-							//this->decodeUtil.SetEmm(this->emmEnableFlag);
-							//ResetErrCount();
+						if(this->catUtil->AddPacket(&packet) == TRUE){
+							CheckNeedPID();
 						}
 					}
-
-				}else{
-					//指定サービスに必要なPIDを解析
-					if( packet.transport_scrambling_control == 0 ){
-						//CAT
-						if( packet.PID == 0x0001 ){
-							if( this->catUtil == NULL ){
-								this->catUtil = new CCATUtil;
-							}
-							if(this->catUtil->AddPacket(&packet) == TRUE){
-								CheckNeedPID();
-							}
-						}
-						//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 = 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 ){
-											CheckNeedPID();
-										}
-									}else{
-										if( itrPmt->second->AddPacket(&packet) == TRUE ){
-											CheckNeedPID();
-										}
+					//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 = 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 ){
+										CheckNeedPID();
+									}
+								}else{
+									if( itrPmt->second->AddPacket(&packet) == TRUE ){
+										CheckNeedPID();
 									}
-								}
-							}
-						}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 ){
-									CheckNeedPID();
 								}
 							}
 						}
-					}
-
-					//デコード用のバッファ作成
-					if( this->serviceOnlyFlag == FALSE ){
-						//全サービス
-						memcpy(this->decodeBuff + this->deocdeBuffWriteSize, data->data + i, 188);
-						this->deocdeBuffWriteSize += 188;
 					}else{
-						//指定サービス
-						if( IsNeedPID(&packet) == TRUE ){
-							if( packet.PID == 0x0000 ){
-								//PATなので必要なサービスのみに絞る
-								BYTE* patBuff = NULL;
-								DWORD patBuffSize = 0;
-								if( patUtil.GetPacket(&patBuff, &patBuffSize) == TRUE ){
-									memcpy(this->decodeBuff + this->deocdeBuffWriteSize, patBuff, patBuffSize);
-									this->deocdeBuffWriteSize += patBuffSize;
-								}
-							}else{
-								memcpy(this->decodeBuff + this->deocdeBuffWriteSize, data->data + i, 188);
-								this->deocdeBuffWriteSize += 188;
+						//PMTの2パケット目かチェック
+						map<WORD, CPMTUtil*>::iterator itrPmt;
+						itrPmt = this->pmtUtilMap.find(packet.PID);
+						if( itrPmt != this->pmtUtilMap.end() ){
+							if( itrPmt->second->AddPacket(&packet) == TRUE ){
+								CheckNeedPID();
 							}
 						}
 					}
-					if( this->epgFile != NULL ){
-						if( packet.PID <= 0x0030 ){
-							DWORD write=0;
-							WriteFile(this->epgFile, data->data + i, 188, &write, NULL);
+				}
+
+				//デコード用のバッファ作成
+				if( this->serviceOnlyFlag == FALSE ){
+					//全サービス
+					memcpy(this->decodeBuff + this->deocdeBuffWriteSize, data->data + i, 188);
+					this->deocdeBuffWriteSize += 188;
+				}else{
+					//指定サービス
+					if( IsNeedPID(&packet) == TRUE ){
+						if( packet.PID == 0x0000 ){
+							//PATなので必要なサービスのみに絞る
+							BYTE* patBuff = NULL;
+							DWORD patBuffSize = 0;
+							if( patUtil.GetPacket(&patBuff, &patBuffSize) == TRUE ){
+								memcpy(this->decodeBuff + this->deocdeBuffWriteSize, patBuff, patBuffSize);
+								this->deocdeBuffWriteSize += patBuffSize;
+							}
+						}else{
+							memcpy(this->decodeBuff + this->deocdeBuffWriteSize, data->data + i, 188);
+							this->deocdeBuffWriteSize += 188;
 						}
 					}
 				}
-			}else{
-				if( this->chChangeFlag == TRUE ){
-					if( GetTimeCount() > this->chChangeTime + 15 ){
-						//15秒以上たってるなら切り替わったとする
-						//OutputDebugString(L"★Ch Change Err NoPacket\r\n");
-						//this->chChangeFlag = FALSE;
-						this->chChangeErr = TRUE;
-						this->lastONID = 0xFFFF;
-						this->lastTSID = 0xFFFF;
-						//this->epgUtil.ClearSectionStatus();
-						//this->decodeUtil.SetNetwork(onid, tsid);
-						//this->decodeUtil.SetEmm(this->emmEnableFlag);
-						//ResetErrCount();
+				if( this->epgFile != NULL ){
+					if( packet.PID <= 0x0030 ){
+						DWORD write=0;
+						WriteFile(this->epgFile, data->data + i, 188, &write, NULL);
 					}
 				}
 			}
+
 		}
 		if( this->chChangeFlag == FALSE ){
 			WORD onid = 0xFFFF;
 			WORD tsid = 0xFFFF;
 			if( this->epgUtil.GetTSID(&onid, &tsid) == NO_ERR ){
 				if( onid != this->lastONID || tsid != this->lastTSID ){
+					// 予期せぬチャンネル変更 - 勝手にチャンネルが切り替わった？
 					OutputDebugString(L"★UnKnown Ch Change \r\n");
 					_OutputDebugString(L"★Ch 0x%04X 0x%04X => 0x%04X 0x%04X\r\n", this->lastONID, this->lastTSID, onid, tsid);
-					this->chChangeFlag = FALSE;
-					this->chChangeErr = FALSE;
-					this->lastONID = onid;
-					this->lastTSID = tsid;
-					this->epgUtil.ClearSectionStatus();
-					if( this->decodeUtil.SetNetwork(onid, tsid) == FALSE ){
-						OutputDebugString(L"★★Decode DLL load err\r\n");
-						Sleep(100);
-						this->decodeUtil.SetNetwork(onid, tsid);
-					}
-					this->decodeUtil.SetEmm(this->emmEnableFlag);
-					ResetErrCount();
-					chChgComp = TRUE;
-
-					map<WORD, CPMTUtil*>::iterator itrPmt;
-					for( itrPmt = this->pmtUtilMap.begin(); itrPmt != this->pmtUtilMap.end(); itrPmt++ ){
-						SAFE_DELETE(itrPmt->second);
-					}
-					this->pmtUtilMap.clear();
-
+					OnChChanged(onid, tsid);
 				}
 			}
 		}
@@ -446,8 +429,9 @@ DWORD CTSOut::AddTSBuff(TS_DATA* data)
 	}
 	try{
 		if( this->deocdeBuffWriteSize > 0 ){
-			if( this->enableDecodeFlag == TRUE && this->chChangeFlag == FALSE && chChgComp == FALSE){
-				//デコード必要
+			if( this->enableDecodeFlag == TRUE && this->chChangeFlag == FALSE){
+				// デコード必要
+				// チャンネル切り替え直後の復号が行われなさそうに思えたので chChgComp == FALSE の比較を除去
 
 				if( decodeUtil.Decode(this->decodeBuff, this->deocdeBuffWriteSize, &decodeData, &decodeSize) == FALSE ){
 					//デコード失敗
@@ -471,7 +455,7 @@ DWORD CTSOut::AddTSBuff(TS_DATA* data)
 		decodeData = this->decodeBuff;
 		decodeSize = this->deocdeBuffWriteSize;
 	}
-	
+
 	//デコード済みのデータを解析させる
 	try{
 		for( DWORD i=0; i<decodeSize; i+=188 ){
@@ -549,7 +533,7 @@ void CTSOut::CheckNeedPID()
 			pidName.insert(pair<WORD, string>(itrPID->first, name));
 		}
 		pidName.insert(pair<WORD, string>(itrPmt->second->PCR_PID, "PCR"));
-		
+
 	}
 
 	//EMMのPID
@@ -640,27 +624,32 @@ BOOL CTSOut::StartSaveEPG(
 	)
 {
 	if( Lock(L"StartSaveEPG") == FALSE ) return FALSE;
-	if( this->epgFile != NULL ){
-		UnLock();
-		return FALSE;
-	}
-	this->epgFilePath = epgFilePath;
-	this->epgTempFilePath = epgFilePath;
-	this->epgTempFilePath += L".tmp";
-
-	_OutputDebugString(L"★%s\r\n", this->epgFilePath.c_str());
-	_OutputDebugString(L"★%s\r\n", this->epgTempFilePath.c_str());
+	try {
+		if( this->epgFile != NULL ){
+			UnLock();
+			return FALSE;
+		}
+		this->epgFilePath = epgFilePath;
+		this->epgTempFilePath = epgFilePath;
+		this->epgTempFilePath += L".tmp";
+
+		_OutputDebugString(L"★%s\r\n", this->epgFilePath.c_str());
+		_OutputDebugString(L"★%s\r\n", this->epgTempFilePath.c_str());
+
+		BOOL ret = TRUE;
+		this->epgFile = _CreateFile2(this->epgTempFilePath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
+		if( this->epgFile == INVALID_HANDLE_VALUE ){
+			this->epgFile = NULL;
+			ret = FALSE;
+			OutputDebugString(L"err\r\n");
+		}
 
-	BOOL ret = TRUE;
-	this->epgFile = _CreateFile2(this->epgTempFilePath.c_str(), GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
-	if( this->epgFile == INVALID_HANDLE_VALUE ){
-		this->epgFile = NULL;
-		ret = FALSE;
-		OutputDebugString(L"err\r\n");
+		UnLock();
+		return ret;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
 	}
-
-	UnLock();
-	return ret;
 }
 
 //EPGデータの保存を終了する
@@ -671,24 +660,29 @@ BOOL CTSOut::StopSaveEPG(
 	)
 {
 	if( Lock(L"StopSaveEPG") == FALSE ) return FALSE;
-	if( this->epgFile == NULL ){
-		UnLock();
-		return FALSE;
-	}
+	try {
+		if( this->epgFile == NULL ){
+			UnLock();
+			return FALSE;
+		}
 
-	CloseHandle(this->epgFile);
-	this->epgFile = NULL;
+		CloseHandle(this->epgFile);
+		this->epgFile = NULL;
 
-	if( copy == TRUE ){
-		CopyFile(this->epgTempFilePath.c_str(), this->epgFilePath.c_str(), FALSE );
-	}
-	DeleteFile(this->epgTempFilePath.c_str());
+		if( copy == TRUE ){
+			CopyFile(this->epgTempFilePath.c_str(), this->epgFilePath.c_str(), FALSE );
+		}
+		DeleteFile(this->epgTempFilePath.c_str());
 
-	this->epgFilePath = L"";
-	this->epgTempFilePath = L"";
+		this->epgFilePath = L"";
+		this->epgTempFilePath = L"";
 
-	UnLock();
-	return TRUE;
+		UnLock();
+		return TRUE;
+	} catch (...){
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 //EPGデータの蓄積状態をリセットする
@@ -696,7 +690,10 @@ void CTSOut::ClearSectionStatus()
 {
 	if( Lock(L"ClearSectionStatus") == FALSE ) return ;
 
-	this->epgUtil.ClearSectionStatus();
+	try {
+		this->epgUtil.ClearSectionStatus();
+	} catch (...) {
+	}
 
 	UnLock();
 	return ;
@@ -713,10 +710,15 @@ EPG_SECTION_STATUS CTSOut::GetSectionStatus(
 {
 	if( Lock(L"GetSectionStatus") == FALSE ) return EpgNoData;
 
-	EPG_SECTION_STATUS status = this->epgUtil.GetSectionStatus(l_eitFlag);
+	try {
+		EPG_SECTION_STATUS status = this->epgUtil.GetSectionStatus(l_eitFlag);
 
-	UnLock();
-	return status;
+		UnLock();
+		return status;
+	} catch (...){
+		UnLock();
+		return EpgNoData;
+	}
 }
 
 //EMM処理の動作設定
@@ -730,11 +732,27 @@ BOOL CTSOut::SetEmm(
 {
 	if( Lock(L"SetEmm") == FALSE ) return FALSE;
 
-	BOOL err = this->decodeUtil.SetEmm(enable);
-	this->emmEnableFlag = enable;
+	try {
+		if ((this->lastONID != 0xffff) && (this->lastTSID != 0xffff)) {
+			// チューニング済みで
+			if ((enable != FALSE) && (this->enableDecodeFlag == FALSE) && (this->emmEnableFlag == FALSE)) {
+				// 最初に EMM 処理が設定される場合は DLL を読み込む
+				// スクランブル解除が設定されている場合は読み込み済みなので除外
+				if (this->decodeUtil.SetNetwork(this->lastONID, this->lastTSID) == FALSE) {
+					OutputDebugString(L"★★Decode DLL load err [CTSOut::SetEmm()]\r\n");
+				}
+			}
+		}
+		
+		BOOL err = this->decodeUtil.SetEmm(enable);
+		this->emmEnableFlag = enable;
 
-	UnLock();
-	return err;
+		UnLock();
+		return err;
+	} catch (...) {
+		UnLock();
+		return FALSE;
+	}
 }
 
 //EMM処理を行った数
@@ -837,17 +855,24 @@ BOOL CTSOut::CreateServiceCtrl(
 {
 	if( Lock(L"CreateServiceCtrl") == FALSE ) return FALSE;
 
-	COneServiceUtil* serviceUtil = new COneServiceUtil;
-	*id = GetNextID();
+	try {
+		COneServiceUtil* serviceUtil = new COneServiceUtil;
+		*id = GetNextID();
 
-	serviceUtil->SetEpgUtil(&this->epgUtil);
-	serviceUtil->SetID(*id);
-	serviceUtil->SetBonDriver(bonFile);
+		serviceUtil->SetEpgUtil(&this->epgUtil);
+		serviceUtil->SetID(*id);
+		serviceUtil->SetBonDriver(bonFile);
 
-	serviceUtilMap.insert(pair<DWORD, COneServiceUtil*>(*id, serviceUtil));
+		serviceUtilMap.insert(pair<DWORD, COneServiceUtil*>(*id, serviceUtil));
 
-	UnLock();
-	return TRUE;
+		UnLock();
+		return TRUE;
+		
+	} catch (...) {
+		
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 //TSストリーム制御用コントロールを作成する
@@ -1189,33 +1214,38 @@ BOOL CTSOut::StartSave(
 	vector<REC_FILE_SET_INFO>* saveFolder,
 	vector<wstring>* saveFolderSub,
 	int maxBuffCount
-)
+	)
 {
 	if( Lock(L"StartSave") == FALSE ) return FALSE;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return FALSE;
-	}
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return FALSE;
+		}
 
-	BOOL ret = itr->second->StartSave(fileName, overWriteFlag, pittariFlag, pittariONID, pittariTSID, pittariSID, pittariEventID, createSize, saveFolder, saveFolderSub, maxBuffCount);
-	if( ret == FALSE ){
-		_OutputDebugString(L"認識ドライブ");
-		WCHAR drive[4] = L"A:\\";
-		for( int i=0; i<26; i++ ){
-			ULARGE_INTEGER stFree;
-			ULARGE_INTEGER stTotal;
-			ULARGE_INTEGER stTotalFree;
-			if( _GetDiskFreeSpaceEx( drive, &stFree, &stTotal, &stTotalFree ) == TRUE ){
-				_OutputDebugString(L"%s free : %I64d byte", drive, stFree.QuadPart);
+		BOOL ret = itr->second->StartSave(fileName, overWriteFlag, pittariFlag, pittariONID, pittariTSID, pittariSID, pittariEventID, createSize, saveFolder, saveFolderSub, maxBuffCount);
+		if( ret == FALSE ){
+			_OutputDebugString(L"認識ドライブ");
+			WCHAR drive[4] = L"A:\\";
+			for( int i=0; i<26; i++ ){
+				ULARGE_INTEGER stFree;
+				ULARGE_INTEGER stTotal;
+				ULARGE_INTEGER stTotalFree;
+				if( _GetDiskFreeSpaceEx( drive, &stFree, &stTotal, &stTotalFree ) == TRUE ){
+					_OutputDebugString(L"%s free : %I64d byte", drive, stFree.QuadPart);
+				}
+				drive[0]++;
 			}
-			drive[0]++;
 		}
+		UnLock();
+		return ret;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
 	}
-	UnLock();
-	return ret;
 }
 
 //ファイル保存を終了する
@@ -1228,18 +1258,23 @@ BOOL CTSOut::EndSave(
 	)
 {
 	if( Lock(L"EndSave") == FALSE ) return FALSE;
-	BOOL ret = TRUE;
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return FALSE;
-	}
+	try {
+		BOOL ret = TRUE;
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return FALSE;
+		}
 
-	ret = itr->second->EndSave();
+		ret = itr->second->EndSave();
 
-	UnLock();
-	return ret;
+		UnLock();
+		return ret;
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 //スクランブル解除処理の動作設定
@@ -1254,27 +1289,44 @@ BOOL CTSOut::SetScramble(
 {
 	if( Lock(L"SetScramble") == FALSE ) return FALSE;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return FALSE;
-	}
+	try {
+		if ((this->lastONID != 0xffff) && (this->lastTSID != 0xffff)) {
+			// チューニング済みで
+			if ((enable != FALSE) && (this->enableDecodeFlag == FALSE) && (this->emmEnableFlag == FALSE)) {
+				// 最初にスクランブル解除が設定される場合は DLL を再読み込みする
+				// EMM 処理が設定されている場合は読み込み済みなので除外
+				if (this->decodeUtil.SetNetwork(this->lastONID, this->lastTSID) == FALSE) {
+					OutputDebugString(L"★★Decode DLL load err [CTSOut::SetScramble()]\r\n");
+				}
+			}
+		}
+		
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return FALSE;
+		}
 
-	itr->second->SetScramble(enable);
+		itr->second->SetScramble(enable);
 
-	BOOL enableScramble = FALSE;
-	for( itr = this->serviceUtilMap.begin(); itr != this->serviceUtilMap.end(); itr++ ){
-		if( itr->second->GetScramble() == TRUE ){
-			enableScramble = TRUE;
-			break;
+		BOOL enableScramble = FALSE;
+		for( itr = this->serviceUtilMap.begin(); itr != this->serviceUtilMap.end(); itr++ ){
+			if( itr->second->GetScramble() == TRUE ){
+				enableScramble = TRUE;
+				break;
+			}
 		}
-	}
 
-	this->enableDecodeFlag = enableScramble;
+		this->enableDecodeFlag = enableScramble;
 
-	UnLock();
-	return TRUE;
+		UnLock();
+		return TRUE;
+		
+	} catch (...) {
+		UnLock();
+		return ERR_FALSE;
+	}
 }
 
 //字幕とデータ放送含めるかどうか
@@ -1290,16 +1342,20 @@ void CTSOut::SetServiceMode(
 {
 	if( Lock(L"SetServiceMode") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->SetServiceMode(enableCaption, enableData);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->SetServiceMode(enableCaption, enableData);
+	} catch (...) {
+	}
+	
 	UnLock();
+		
 }
 
 //エラーカウントをクリアする
@@ -1311,15 +1367,18 @@ void CTSOut::ClearErrCount(
 {
 	if( Lock(L"ClearErrCount") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->ClearErrCount();
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->ClearErrCount();
+	} catch (...) {
+	}
+	
 	UnLock();
 }
 
@@ -1336,15 +1395,18 @@ void CTSOut::GetErrCount(
 {
 	if( Lock(L"GetErrCount") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->GetErrCount(drop, scramble);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->GetErrCount(drop, scramble);
+	} catch (...){
+	}
+	
 	UnLock();
 }
 
@@ -1360,15 +1422,18 @@ void CTSOut::GetRecWriteSize(
 {
 	if( Lock(L"GetRecWriteSize") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->GetRecWriteSize(writeSize);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->GetRecWriteSize(writeSize);
+	} catch (...){
+	}
+	
 	UnLock();
 }
 
@@ -1393,15 +1458,18 @@ void CTSOut::GetSaveFilePath(
 {
 	if( Lock(L"GetSaveFilePath") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->GetSaveFilePath(filePath, subRecFlag);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->GetSaveFilePath(filePath, subRecFlag);
+	} catch (...) {
+	}
+	
 	UnLock();
 }
 
@@ -1416,15 +1484,18 @@ void CTSOut::SaveErrCount(
 {
 	if( Lock(L"SaveErrCount") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	itr = serviceUtilMap.find(id);
-	if( itr == serviceUtilMap.end() ){
-		UnLock();
-		return ;
-	}
-
-	itr->second->SaveErrCount(filePath);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		itr = serviceUtilMap.find(id);
+		if( itr == serviceUtilMap.end() ){
+			UnLock();
+			return ;
+		}
 
+		itr->second->SaveErrCount(filePath);
+	} catch (...){
+	}
+	
 	UnLock();
 }
 
@@ -1434,9 +1505,12 @@ void CTSOut::SetSignalLevel(
 {
 	if( Lock(L"SetSignalLevel") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	for( itr = serviceUtilMap.begin(); itr != serviceUtilMap.end(); itr++ ){
-		itr->second->SetSignalLevel(signalLv);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		for( itr = serviceUtilMap.begin(); itr != serviceUtilMap.end(); itr++ ){
+			itr->second->SetSignalLevel(signalLv);
+		}
+	} catch (...) {
 	}
 
 	UnLock();
@@ -1449,12 +1523,15 @@ void CTSOut::SetBonDriver(
 {
 	if( Lock(L"SetBonDriver") == FALSE ) return ;
 
-	map<DWORD, COneServiceUtil*>::iterator itr;
-	for( itr = serviceUtilMap.begin(); itr != serviceUtilMap.end(); itr++ ){
-		itr->second->SetBonDriver(bonDriver);
+	try {
+		map<DWORD, COneServiceUtil*>::iterator itr;
+		for( itr = serviceUtilMap.begin(); itr != serviceUtilMap.end(); itr++ ){
+			itr->second->SetBonDriver(bonDriver);
+		}
+		bonFile = bonDriver;
+	} catch (...) {
 	}
-	bonFile = bonDriver;
-
+	
 	UnLock();
 }
 
diff --git a/BonCtrl/TSOut.h b/BonCtrl/TSOut.h
index 7bd32e5..04c5a7b 100644
--- a/BonCtrl/TSOut.h
+++ b/BonCtrl/TSOut.h
@@ -365,5 +365,8 @@ protected:
 	BOOL ConvertEpgInfo(EPG_EVENT_INFO* src, EPGDB_EVENT_INFO* dest);
 
 	void ResetErrCount();
+
+	BOOL CheckChChangeCompletion(WORD onid, WORD tsid) const;
+	void OnChChanged(WORD onid, WORD tsid);
 };
 
