示例#1
0
    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
示例#2
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)
示例#3
0
 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
示例#4
0
    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)
示例#5
0
    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?
示例#6
0
 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))
示例#8
0
    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))
示例#9
0
    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 = []
示例#10
0
    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)
示例#11
0
    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()
示例#12
0
    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()