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; }
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; }