int ExtractThread(EXTRACT_THREAD_VIDEO_DATA*	lpETD)
{
	lpETD->dlg->SetDialogState_Muxing();
	lpETD->dlg->ButtonState_START();

	lpETD->dlg->AddProtocolLine("started extracting binary", 4);

	VIDEOSOURCE* v = lpETD->v;
	v->Enable(1);
	CFileStream* f = lpETD->file;
	char cTime[20];
	char* lpBuffer = new char[2<<20];
	int iLastTime = GetTickCount();
	v->ReInit();

	while (!v->IsEndOfStream() && !DoStop()) {
		__int64 iTimecode;
		__int64 iNS = 0;
		DWORD dwSize;
		v->GetFrame(lpBuffer,&dwSize,&iTimecode);
		f->Write(lpBuffer,dwSize);
		if (GetTickCount()-iLastTime>100 || v->IsEndOfStream()) {
			Millisec2Str((iTimecode * v->GetTimecodeScale() + iNS)/ 1000000,cTime);
			
			CUTF8 utf8Time(cTime);
			lpETD->dlg->m_Prg_Frames.SetWindowText(utf8Time.TStr());
			iLastTime+=100;
		}
	}

	lpETD->dlg->SetDialogState_Config();
	lpETD->dlg->ButtonState_STOP();
	delete lpBuffer;
	StopMuxing(false);
	lpETD->file->Close();
	lpETD->dlg->AddProtocol_Separator();
	delete lpETD;

	v->Enable(0);

	return 1;
}
Exemple #2
0
int CDownload::_ProcessSegment( CRequestPool &request_pool, CSegmentPool &pool, DWORD dwWaitRet, CFileStream &fs, BOOL &gotData )
{
	int ret = 0;
	BOOL bSegmentDone = FALSE;
	int idx = dwWaitRet - 1;
	SegmentPtrs &runnings = pool.GetRunningSegments();
	Segment &s = *runnings[idx];
	CHttpAsyncIn &http = *s.instream;
	EAsyncInState st = http.Process();
	gotData = EAsync_Data==st;
	
	if(EAsync_Finished==st && s.endposition>0 && !s.isDone())
	{
		// 块应该没有下载完成 !		
		MYTRACE(_T("Unfinished Segment(%d) %I64d - %I64d - %I64d\r\n"), s.index, s.startposition, s.currentposition, s.endposition);
		st = EAsync_Failed;
	}

	if( EAsync_Finished==st && s.instream && s.instream->IsLastValidBufferZeroBit() )
	{
		MYTRACE(_T("Finished (BUT LAST BUFFER 1.ZERO) Segment(%d) %I64d - %I64d - %I64d\r\n"), s.index, s.startposition, s.currentposition, s.endposition);
		st = EAsync_Failed;
	}
	
	if(EAsync_Failed==st)
	{
		// NOTE: 需要回滚数据!!! 
		MYTRACE(_T("Queuing Failed Segment(%d) %I64d - %I64d - %I64d\r\n"), s.index, s.startposition, s.currentposition, s.endposition);
		const UrlInfo * urlinfo = s.instream->GetLocationInfo();
		m_locationPool.Put(urlinfo->szUrl, TRUE);
		
		BOOL toRollback = s.instream->IsLastValidBufferZeroBit();

		request_pool.Put( s.instream );
		s.instream = NULL;

		// 回滚 
		if(toRollback)
		{
			_RollbackSegment(s);
		}
		
#if 0 
		if(s.endposition>0)
		{
			int64 iDownloaded = s.currentposition - s.startposition;
			if((s.currentposition-s.startposition) < HTTP_RECEIVE_BUFFER_LENGTH)
			{
				s.currentposition = s.startposition;
			}
			else
			{
				s.currentposition -= HTTP_RECEIVE_BUFFER_LENGTH;
			}
			if((s.currentposition-s.startposition) < MIN_BLOCK)
			{
				s.currentposition = s.startposition;
			}
			
			int64 iDiff = iDownloaded - (s.currentposition - s.startposition);
			m_FileInfo.fileDownloaded -= iDiff; // 回滚下载长度 
			MYTRACE(_T("Rollback Failed Segment(%d) %I64d - %I64d - %I64d  (%d) BYTE\r\n"), s.index, s.startposition, s.currentposition, s.endposition, iDiff);
		}
#endif 

		pool.Put(&s);
		//TODO :notify fail 
		return 1;
	}
	else if(EAsync_Data==st)
	{		
		INTERNET_BUFFERSA *pInetBuff = (INTERNET_BUFFERSA *)http.GetLastBuffer();
		DWORD dwToWrite = pInetBuff->dwBufferLength;
		DWORD dwWrite = 0;
		
		//MYTRACE(_T("%I64d - %I64d - %I64d  %d\r\n"), s.startposition, s.currentposition, s.endposition, dwToWrite);
		if(s.endposition>0)
		{
			ATLASSERT(s.endposition>s.startposition && s.endposition>s.currentposition);
			ATLASSERT(dwToWrite>0 && s.endposition-s.currentposition);
			ATLASSERT(dwToWrite<=(s.endposition-s.currentposition));
			dwToWrite = min(s.endposition-s.currentposition, dwToWrite);
		}
		if (!fs.Write(s.currentposition, pInetBuff->lpvBuffer, dwToWrite, &dwWrite))
		{
			MYTRACE( _T("ProcessState_ReceiveData Write Error: %d/%d\r\n"), dwWrite/dwToWrite );
			m_errCode = DLERR_WRITEFILE;
			return -1;
		}
		else
		{
			s.currentposition += dwToWrite;
			m_FileInfo.fileDownloaded += dwToWrite;
			m_downStat.OnDownData(dwToWrite);
			return 0;
		}
	}
	else if(EAsync_Finished==st)
	{
		ATLASSERT(s.isDone() || s.endposition==-1);
		s.instream->Process();	// 最后close 		

		MYTRACE(_T("Part %d(%I64d-%I64d-%I64d) Done\r\n"), s.index, s.startposition, s.currentposition, s.endposition);
		SegmentPtr pnext = pool.GetNextSegment(&s);
		if(pnext)
		{
			ATLASSERT(pnext->instream!=s.instream);
			if(pnext->instream)
			{
				request_pool.Put(pnext->instream);
				pnext->instream = NULL;
			}
			if(pnext->currentposition==s.endposition)
			{
				// Reuse the connection 
				pnext->instream = s.instream;
				s.instream = NULL;
				pnext->instream->Continue(pnext->currentposition, pnext->endposition);
			}
			else
			{
				// New Connection 
				pnext->instream = s.instream;
				s.instream = NULL;
				pnext->instream->OpenRange(pnext->currentposition, pnext->endposition);
			}
			pool.NotifySegmentToRunning(pnext);
		}
		else
		{
			const UrlInfo * urlinfo = s.instream->GetLocationInfo();
			m_locationPool.Put(urlinfo->szUrl, FALSE);

			request_pool.Put( s.instream );
			s.instream = NULL;
		}
		ATLASSERT(s.instream==NULL);
		pool.Put(&s);
		return 1;
	}
	return 0;
}