def __init__(self, downloader, connection): self.downloader = downloader self.connection = connection self.choked = True self.interested = False self.active_requests = [] self.measure = Measure(downloader.max_rate_period) self.peermeasure = Measure(downloader.max_rate_period) self.have = Bitfield(downloader.numpieces) self.last = -1000 self.last2 = -1000 self.example_interest = None self.backlog = 2 self.ip = connection.get_ip() self.guard = BadDataGuard(self) # boudewijn: VOD needs a download measurement that is not # averaged over a 'long' period. downloader.max_rate_period is # (by default) 20 seconds because this matches the unchoke # policy. self.short_term_measure = Measure(5) # boudewijn: each download maintains a counter for the number # of high priority piece requests that did not get any # responce within x seconds. self.bad_performance_counter = 0
def __init__(self, proxydownloader, proxy_permid): self.downloader = proxydownloader self.proxy_permid = proxy_permid self.connection = None self.measure = Measure(self.downloader.max_rate_period) self.active_requests = { } # dictionary with all indexes currently being downloaded. Key: index, value: timestamp (the moment when the piece was requested) self.piece_size = self.downloader.storage._piecelen(0) self.total_len = self.downloader.storage.total_length self.requests = { } # dictionary of lists: requests[index] contains a list of all reserved chunks self.request_size = {} # dictionary of piece sizes self.received_data = {} # a dictionary of piece data self.endflag = False self.error = None self.retry_period = 0 #30 self._retry_period = None self.errorcount = 0 self.active = False self.cancelled = False self.numpieces = self.downloader.numpieces self.proxy_have = Bitfield(self.downloader.numpieces) self.first_piece_request = True # boudewijn: VOD needs a download measurement that is not # averaged over a 'long' period. downloader.max_rate_period is # (by default) 20 seconds because this matches the unchoke # policy. self.short_term_measure = Measure(SHORT_TERM_MEASURE_INTERVAL) # boudewijn: each download maintains a counter for the number # of high priority piece requests that did not get any # responce within x seconds. self.bad_performance_counter = 0 # HTTP Video Support self.request_lock = Lock() self.video_support_policy = False # TODO : get from constructor parameters self.video_support_enabled = False # Don't start immediately with support self.video_support_speed = 0.0 # Start with the faster rescheduling speed self.video_support_slow_start = False # If enabled delay the first request (give chance to peers to give bandwidth) # Arno, 2010-04-07: Wait 1 second before using HTTP seed. TODO good policy # If Video Support policy is not eneabled then use Http seed normaly if not self.video_support_policy: self.resched(1)
def __init__(self, downloader, connection): # 2fastbt_ SingleDownloadHelperInterface.__init__(self) # _2fastbt self.downloader = downloader self.connection = connection self.choked = True self.interested = False self.active_requests = [] self.measure = Measure(downloader.max_rate_period) self.peermeasure = Measure(downloader.max_rate_period) self.have = Bitfield(downloader.numpieces) self.last = -1000 self.last2 = -1000 self.example_interest = None self.backlog = 2 self.ip = connection.get_ip() self.guard = BadDataGuard(self) # 2fastbt_ self.helper = downloader.picker.helper
def __init__(self, downloader, url, video_support_policy): self.downloader = downloader self.baseurl = url try: (self.scheme, self.netloc, path, pars, query, fragment) = urlparse(url) except: self.downloader.errorfunc('cannot parse http seed address: ' + url) return if self.scheme != 'http': self.downloader.errorfunc('http seed url not http: ' + url) return # Arno, 2010-03-08: Make proxy aware self.proxyhost = find_proxy(url) try: if self.proxyhost is None: self.connection = HTTPConnection(self.netloc) else: self.connection = HTTPConnection(self.proxyhost) except: self.downloader.errorfunc('cannot connect to http seed: ' + url) return self.seedurl = path self.measure = Measure(downloader.max_rate_period) self.index = None self.piece_size = self.downloader.storage._piecelen(0) self.total_len = self.downloader.storage.total_length self.url = '' self.requests = [] self.request_size = 0 self.endflag = False self.error = None self.retry_period = 30 self._retry_period = None self.errorcount = 0 self.goodseed = False self.active = False self.cancelled = False # HTTP Video Support self.request_lock = Lock() self.video_support_policy = video_support_policy # Niels: 08-03-2012 using svc_video or play_video in download_bt1 self.video_support_enabled = False # Don't start immediately with support self.video_support_speed = 0.0 # Start with the faster rescheduling speed self.video_support_slow_start = False # If enabled delay the first request (give chance to peers to give bandwidth) # Arno, 2010-04-07: Wait 1 second before using HTTP seed. TODO good policy # If Video Support policy is not eneabled then use Http seed normaly if not self.video_support_policy: self.resched(1)
def __init__(self, connection, connecter): self.connection = connection self.connecter = connecter self.got_anything = False self.next_upload = None self.outqueue = [] self.partial_message = None self.download = None self.downloader = None self.upload = None self.send_choke_queued = False self.just_unchoked = None self.unauth_permid = None self.looked_for_permid = UNAUTH_PERMID_PERIOD - 3 self.closed = False self.extend_hs_dict = { } # what extended messages does this peer support self.initiated_overlay = False # G2G self.use_g2g = False # set to true if both sides use G2G, indicated by self.connector.use_g2g self.g2g_version = None self.perc_sent = {} # batch G2G_XFER information and periodically send it out. self.last_perc_sent = {} config = self.connecter.config self.forward_speeds = [0] * 2 self.forward_speeds[0] = Measure(config['max_rate_period'], config['upload_rate_fudge']) self.forward_speeds[1] = Measure(config['max_rate_period'], config['upload_rate_fudge']) # BarterCast counters self.total_downloaded = 0 self.total_uploaded = 0 self.ut_pex_first_flag = True # first time we sent a ut_pex to this peer?
def __init__(self, storage, picker, backlog, max_rate_period, numpieces, chunksize, measurefunc, snub_time, kickbans_ok, kickfunc, banfunc, scheduler=None): self.storage = storage self.picker = picker self.backlog = backlog self.max_rate_period = max_rate_period self.measurefunc = measurefunc self.totalmeasure = Measure(max_rate_period * storage.piece_length / storage.request_size) self.numpieces = numpieces self.chunksize = chunksize self.snub_time = snub_time self.kickfunc = kickfunc self.banfunc = banfunc self.disconnectedseeds = {} self.downloads = [] self.perip = {} self.gotbaddata = {} self.kicked = {} self.banned = {} self.kickbans_ok = kickbans_ok self.kickbans_halted = False self.super_seeding = False self.endgamemode = False self.endgame_queued_pieces = [] self.all_requests = [] self.discarded = 0L # self.download_rate = 25000 # 25K/s test rate self.download_rate = 0 self.bytes_requested = 0 self.last_time = clock() self.queued_out = {} self.requeueing = False self.paused = False self.scheduler = scheduler
def __init__(self, downloader, url): self.downloader = downloader self.baseurl = url try: (self.scheme, self.netloc, path, pars, query, fragment) = urlparse(url) except: self.downloader.errorfunc('cannot parse http seed address: ' + url) return if self.scheme != 'http': self.downloader.errorfunc('http seed url not http: ' + url) return # Arno, 2010-03-08: Make proxy aware self.proxyhost = find_proxy(url) try: if self.proxyhost is None: self.connection = HTTPConnection(self.netloc) else: self.connection = HTTPConnection(self.proxyhost) except: self.downloader.errorfunc('cannot connect to http seed: ' + url) return self.seedurl = path if pars: self.seedurl += ';' + pars self.seedurl += '?' if query: self.seedurl += query + '&' self.seedurl += 'info_hash=' + urllib.quote(self.downloader.infohash) self.measure = Measure(downloader.max_rate_period) self.index = None self.url = '' self.requests = [] self.request_size = 0 self.endflag = False self.error = None self.retry_period = 30 self._retry_period = None self.errorcount = 0 self.goodseed = False self.active = False self.cancelled = False self.resched(randint(2, 10))
def __init__(self, downloader, url): # 2fastbt_ SingleDownloadHelperInterface.__init__(self) # _2fastbt self.downloader = downloader self.baseurl = url try: (scheme, self.netloc, path, pars, query, fragment) = urlparse(url) except: self.downloader.errorfunc('cannot parse http seed address: ' + url) return if scheme != 'http': self.downloader.errorfunc('http seed url not http: ' + url) return try: self.connection = HTTPConnection(self.netloc) except: self.downloader.errorfunc('cannot connect to http seed: ' + url) return self.seedurl = path if pars: self.seedurl += ';' + pars self.seedurl += '?' if query: self.seedurl += query + '&' self.seedurl += 'info_hash=' + quote(self.downloader.infohash) self.measure = Measure(downloader.max_rate_period) self.index = None self.url = '' self.requests = [] self.request_size = 0 self.endflag = False self.error = None self.retry_period = 30 self._retry_period = None self.errorcount = 0 self.goodseed = False self.active = False self.cancelled = False self.resched(randint(2, 10))
def __init__(self, connection, ratelimiter, totalup, choker, storage, picker, config): self.connection = connection self.ratelimiter = ratelimiter self.totalup = totalup self.choker = choker self.storage = storage self.picker = picker self.config = config self.max_slice_length = config['max_slice_length'] self.choked = True self.cleared = True self.interested = False self.super_seeding = False self.buffer = [] self.measure = Measure(config['max_rate_period'], config['upload_rate_fudge']) self.was_ever_interested = False if storage.get_amount_left() == 0: if choker.super_seed: self.super_seeding = True # flag, and don't send bitfield self.seed_have_list = [] # set from piecepicker self.skipped_count = 0 else: if config['breakup_seed_bitfield']: bitfield, msgs = storage.get_have_list_cloaked() connection.send_bitfield(bitfield) for have in msgs: connection.send_have(have) else: connection.send_bitfield(storage.get_have_list()) else: if storage.do_I_have_anything(): connection.send_bitfield(storage.get_have_list()) self.piecedl = None self.piecebuf = None # Merkle self.hashlist = []
def __init__(self, infohash, storage, picker, backlog, max_rate_period, numpieces, chunksize, measurefunc, snub_time, kickbans_ok, kickfunc, banfunc, bt1dl, scheduler=None): self.infohash = infohash self.b64_infohash = b64encode(infohash) self.storage = storage self.picker = picker self.backlog = backlog self.max_rate_period = max_rate_period self.measurefunc = measurefunc self.totalmeasure = Measure(max_rate_period * storage.piece_length / storage.request_size) self.numpieces = numpieces self.chunksize = chunksize self.snub_time = snub_time self.kickfunc = kickfunc self.banfunc = banfunc self.disconnectedseeds = {} self.downloads = [] self.perip = {} self.gotbaddata = {} self.kicked = {} self.banned = {} self.kickbans_ok = kickbans_ok self.kickbans_halted = False self.super_seeding = False self.endgamemode = False self.endgame_queued_pieces = [] self.all_requests = [] self.discarded = 0L self.download_rate = 0 # self.download_rate = 25000 # 25K/s test rate self.bytes_requested = 0 self.last_time = clock() self.queued_out = {} self.requeueing = False self.paused = False self.scheduler = scheduler # ProxyService_ # self.bt1dl = bt1dl self.proxydownloader = None # # _ProxyService # hack: we should not import this since it is not part of the # core nor should we import here, but otherwise we will get # import errors # # _event_reporter stores events that are logged somewhere... # from Tribler.Core.Statistics.StatusReporter import get_reporter_instance # self._event_reporter = get_reporter_instance() self._event_reporter = get_status_holder("LivingLab") # check periodicaly self.scheduler(self.dlr_periodic_check, 1)
def start( self, bytepos = 0, force = False ): """ Initialise to start playing at position `bytepos'. """ self._playback_stats.add_event(self._playback_key, "play") # ARNOTODO: we don't use start(bytepos != 0) at the moment. See if we # should. Also see if we need the read numbytes here, or that it # is better handled at a higher layer. For live it is currently # done at a higher level, see VariableReadAuthStreamWrapper because # we have to strip the signature. Hence the self.curpiece buffer here # is superfluous. Get rid off it or check if # # curpiece[0:piecelen] # # returns curpiece if piecelen has length piecelen == optimize for # piecesized case. # # For VOD seeking we may use the numbytes facility to seek to byte offsets # not just piece offsets. # vs = self.videostatus if vs.playing and not force: return # lock before changing startpos or any other playing variable self.data_ready.acquire() try: # Determine piece number and offset if bytepos < vs.piecelen: piece = vs.first_piece offset = bytepos else: newbytepos = bytepos - vs.first_piecelen piece = vs.first_piece + newbytepos / vs.piecelen + 1 offset = newbytepos % vs.piecelen if DEBUG: print >>sys.stderr,"vod: trans: === START, START, START, START, START, START, START, START, START, START, START, START, START,START" print >>sys.stderr,"vod: trans: === START at offset %d (piece %d) (forced: %s) ===" % (bytepos,piece,force) # Initialise all playing variables self.curpiece = "" # piece currently being popped self.curpiece_pos = offset # TODO self.set_pos( piece ) self.outbuf = [] #self.last_pop = time.time() self.reset_bitrate_prediction() vs.playing = True self.playbackrate = Measure( 60 ) finally: self.data_ready.release() # ARNOTODO: start is called by non-NetworkThreads, these following methods # are usually called by NetworkThread. # # We now know that this won't be called until notify_playable() so # perhaps this can be removed? # # CAREFUL: if we use start() for seeking... that's OK. User won't be # able to seek before he got his hands on the stream, so after # notify_playable() # See what we can do right now self.update_prebuffering() self.refill_buffer()
def __init__(self,bt1download,videostatus,videoinfo,videoanalyserpath,vodeventfunc): # dirty hack to get the Tribler Session from Tribler.Core.Session import Session session = Session.get_instance() if session.get_overlay(): # see comment in else section on importing... from Tribler.Core.CacheDB.SqliteVideoPlaybackStatsCacheDB import VideoPlaybackDBHandler self._playback_stats = VideoPlaybackDBHandler.get_instance() else: # hack: we should not import this since it is not part of # the core nor should we import here, but otherwise we # will get import errors from Tribler.Player.Reporter import VideoPlaybackReporter self._playback_stats = VideoPlaybackReporter.get_instance() # add an event to indicate that the user wants playback to # start def set_nat(nat): self._playback_stats.add_event(self._playback_key, "nat:%s" % nat) self._playback_key = base64.b64encode(os.urandom(20)) self._playback_stats.add_event(self._playback_key, "play-init") self._playback_stats.add_event(self._playback_key, "piece-size:%d" % videostatus.piecelen) self._playback_stats.add_event(self._playback_key, "num-pieces:%d" % videostatus.movie_numpieces) self._playback_stats.add_event(self._playback_key, "bitrate:%d" % videostatus.bitrate) self._playback_stats.add_event(self._playback_key, "nat:%s" % session.get_nat_type(callback=set_nat)) self._complete = False self.videoinfo = videoinfo self.bt1download = bt1download self.piecepicker = bt1download.picker self.rawserver = bt1download.rawserver self.storagewrapper = bt1download.storagewrapper self.fileselector = bt1download.fileselector self.vodeventfunc = vodeventfunc self.videostatus = vs = videostatus # Add quotes around path, as that's what os.popen() wants on win32 if sys.platform == "win32" and videoanalyserpath is not None and videoanalyserpath.find(' ') != -1: self.video_analyser_path='"'+videoanalyserpath+'"' else: self.video_analyser_path=videoanalyserpath # counter for the sustainable() call. Every X calls the # buffer-percentage is updated. self.sustainable_counter = sys.maxint # boudewijn: because we now update the downloadrate for each # received chunk instead of each piece we do not need to # average the measurement over a 'long' period of time. Also, # we only update the downloadrate for pieces that are in the # high priority range giving us a better estimation on how # likely the pieces will be available on time. self.overall_rate = Measure(10) self.high_range_rate = Measure(2) # buffer: a link to the piecepicker buffer self.has = self.piecepicker.has # number of pieces in buffer self.pieces_in_buffer = 0 self.data_ready = Condition() # Arno: Call FFMPEG only if the torrent did not provide the # bitrate and video dimensions. This is becasue FFMPEG # sometimes hangs e.g. Ivaylo's Xvid Finland AVI, for unknown # reasons # Arno: 2007-01-06: Since we use VideoLan player, videodimensions not important assert vs.bitrate_set self.doing_ffmpeg_analysis = False self.doing_bitrate_est = False self.videodim = None #self.movieselector.videodim self.player_opened_with_width_height = False self.ffmpeg_est_bitrate = None prebufsecs = self.PREBUF_SEC_VOD # assumes first piece is whole (first_piecelen == piecelen) piecesneeded = vs.time_to_pieces( prebufsecs ) bytesneeded = piecesneeded * vs.piecelen self.max_prebuf_packets = min(vs.movie_numpieces, piecesneeded) if self.doing_ffmpeg_analysis and DEBUG: print >>sys.stderr,"vod: trans: Want",self.max_prebuf_packets,"pieces for FFMPEG analysis, piecesize",vs.piecelen if DEBUG: print >>sys.stderr,"vod: trans: Want",self.max_prebuf_packets,"pieces for prebuffering" self.nreceived = 0 if DEBUG: print >>sys.stderr,"vod: trans: Setting MIME type to",self.videoinfo['mimetype'] self.set_mimetype(self.videoinfo['mimetype']) # some statistics self.stat_playedpieces = 0 # number of pieces played successfully self.stat_latepieces = 0 # number of pieces that arrived too late self.stat_droppedpieces = 0 # number of pieces dropped self.stat_stalltime = 0.0 # total amount of time the video was stalled self.stat_prebuffertime = 0.0 # amount of prebuffer time used self.stat_pieces = PieceStats() # information about each piece # start periodic tasks self.curpiece = "" self.curpiece_pos = 0 # The outbuf keeps only the pieces from the base layer.. We play if we # have at least a piece from the base layer! self.outbuf = [] #self.last_pop = None # time of last pop self.reset_bitrate_prediction() self.lasttime=0 # For DownloadState self.prebufprogress = 0.0 self.prebufstart = time.time() self.playable = False self.usernotified = False self.outbuflen = None # LIVESOURCEAUTH self.authenticator = None self.refill_rawserv_tasker() self.tick_second() # link to others (last thing to do) self.piecepicker.set_transporter( self ) #self.start() if FAKEPLAYBACK: import threading class FakeReader(threading.Thread): def __init__(self,movie): threading.Thread.__init__(self) self.movie = movie def run(self): self.movie.start() while not self.movie.done(): self.movie.read() t = FakeReader(self) t.start()