void LiveDownloadDriver::OnDataRateChanged() { // 保留在切换码流前的校验失败次数,但是在下面这种情况,统计的校验失败次数会比实际的偏大, // 如果A->B->A,而切换前 A 对应的LiveInstance的校验计算结果>0,而且全部切换的时间小于120秒, // 那A对应的LiveInstance还在缓存中而被重用,因而A的校验次数会被重复统计。 // 我们认为偏大的值可以接受,所以在这没有精确计算校验失败次数 checksum_failed_times_ += live_streams_[data_rate_manager_.GetLastDataRatePos()]->GetInstance()->GetChecksumFailedTimes(); bool http_paused = live_streams_[data_rate_manager_.GetLastDataRatePos()]->GetHttpDownloader()->IsPausing(); bool p2p_paused = true; if (live_streams_[data_rate_manager_.GetLastDataRatePos()]->GetP2PDownloader()) { live_streams_[data_rate_manager_.GetLastDataRatePos()]->GetP2PDownloader()->IsPausing(); p2p_paused = false; } CalcCdnAccelerationStatusWhenStop(data_rate_manager_.GetLastDataRatePos()); for (vector<LiveStream__p>::iterator iter = live_streams_.begin(); iter != live_streams_.end(); ++iter) { (*iter)->Stop(); } live_streams_[data_rate_manager_.GetCurrentDataRatePos()]->Start(GetPlayingPosition().GetBlockId()); // HttpDownloader的下载状态恢复 if (!http_paused) { GetHTTPControlTarget()->Resume(); } // P2PDownloader的下载状态恢复 if (!p2p_paused) { GetP2PControlTarget()->Resume(); } }
EC_VOID EngGetPlayingPosition(MediaEngineHandle handle, EC_U32 *pPosition) { GetPlayingPosition(handle, pPosition); }
void LiveDownloadDriver::OnTimerElapsed(framework::timer::Timer * pointer) { if (pointer == &timer_) { if (playing_position_.GetSubPieceIndex() == 0) { JumpOrSwitchIfNeeded(); } #ifndef STATISTIC_OFF UpdateStatisticInfo(); statistic_->UpdateShareMemory(); #endif if (http_download_max_speed_ < GetHTTPControlTarget()->GetSpeedInfo().NowDownloadSpeed) { http_download_max_speed_ = GetHTTPControlTarget()->GetSpeedInfo().NowDownloadSpeed; } if (GetP2PControlTarget()) { if (p2p_download_max_speed_ < GetP2PControlTarget()->GetSpeedInfo().NowDownloadSpeed) { p2p_download_max_speed_ = GetP2PControlTarget()->GetSpeedInfo().NowDownloadSpeed; } if (udp_server_max_speed_ < GetP2PControlTarget()->GetUdpServerSpeedInfo().NowDownloadSpeed) { udp_server_max_speed_ = GetP2PControlTarget()->GetUdpServerSpeedInfo().NowDownloadSpeed; } } ++elapsed_seconds_since_started_; if (bufferring_monitor_) { if (elapsed_seconds_since_started_ > 10 && GetRestPlayableTime() <= 1) { boost::uint32_t data_rate = GetDataRate(); if (data_rate > 0) { storage::LivePosition live_position = GetPlayingPosition(); boost::uint32_t bufferring_position_in_seconds = live_position.GetBlockId()*GetInstance()->GetLiveInterval() + live_position.GetSubPieceIndex()*storage::HeaderSubPiece::Constants::SubPieceSizeInBytes/data_rate; bufferring_monitor_->BufferringOccurs(bufferring_position_in_seconds); } } } if (max_upload_speed_during_this_connection_ < statistic::UploadStatisticModule::Inst()->GetUploadSpeed()) { max_upload_speed_during_this_connection_ = statistic::UploadStatisticModule::Inst()->GetUploadSpeed(); } total_upload_connection_count_ += statistic::UploadStatisticModule::Inst()->GetUploadCount(); if (statistic::UploadStatisticModule::Inst()->GetUploadCount() != 0) { ++time_of_nonblank_upload_connections_; } rest_playable_times_.push_back(GetRestPlayableTime()); if (tick_count_since_last_recv_subpiece_.elapsed() > 180 * 1000 && !is_notify_restart_ && ((GetHTTPControlTarget() && !GetHTTPControlTarget()->IsPausing()) || (GetP2PControlTarget() && !GetP2PControlTarget()->IsPausing()))) { #ifdef PEER_PC_CLIENT WindowsMessage::Inst().PostWindowsMessage(UM_LIVE_RESTART, NULL, NULL); is_notify_restart_ = true; max_push_data_interval_ = tick_count_since_last_recv_subpiece_.elapsed(); #endif } if (udpserver_count_ != UdpServerFromBSPool::Inst()->GetUdpServerCount()) { udpserver_count_ = UdpServerFromBSPool::Inst()->GetUdpServerCount(); AddLiveUdpServerFromBS(); } } }