def GET(self, name): try: capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name)) videofile = capture.get_video() data = videofile.getvalue() web.header('Content-Type', 'video/webm') # Using idea from here: # http://vanderwijk.info/2010/9/17/implementing-http-206-partial-content-support-for-web-py range = web.ctx.env.get('HTTP_RANGE') if range is None: web.header('Content-Length', len(data)) return data total = len(data) _, r = range.split("=") partial_start, partial_end = r.split("-") start = int(partial_start) if not partial_end: end = total - 1 else: end = int(partial_end) chunksize = (end - start) + 1 web.ctx.status = "206 Partial Content" web.header("Content-Range", "bytes %d-%d/%d" % (start, end, total)) web.header("Accept-Ranges", "bytes") web.header("Content-Length", chunksize) return data[start:end + 1] except: raise web.notfound()
def GET(self, name, num): params, body = templeton.handlers.get_request_parms() (width, height) = (params.get('width'), params.get('height')) capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name)) im = capture.get_frame_image(int(num)) if width and height: im.thumbnail((int(width[0]), int(height[0])), Image.ANTIALIAS) return im
def GET(self, name): capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name)) percents = videocapture.get_checkerboarding_percents(capture) area_duration = videocapture.get_checkerboarding_area_duration(capture) return { "areaDuration": area_duration, "numCheckerboards": len(filter(lambda f: f > 0.0, percents)), "numFrames": capture.num_frames }
def GET(self, name): try: capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name)) return dict( { "id": name, "length": capture.num_frames / 60.0, "numFrames": capture.num_frames }, **capture.metadata) except: raise web.notfound()
def GET(self): captures = [] for fname in os.listdir(CAPTURE_DIR): if fname == ".gitignore" or os.path.splitext(fname)[1] <> '.zip': continue try: capture = videocapture.Capture(os.path.join( CAPTURE_DIR, fname)) if capture.num_frames > 0: captures.append( dict( { "id": fname, "length": capture.num_frames / 60.0, "numFrames": capture.num_frames }, **capture.metadata)) except videocapture.BadCapture, error: print "File %s unreadable: %s" % (fname, str(error)) # just ignore files that aren't readable as captures pass
capture_file=capture_file, wifi_settings_file=wifi_settings_file, sync_time=sync_time) test_completed = True break except eideticker.TestException, e: if e.can_retry: print "Test failed, but not fatally. Retrying..." else: raise if not test_completed: raise Exception("Failed to run test %s for %s (after 3 tries). " "Aborting." % (testinfo['key'], productname)) capture = videocapture.Capture(capture_file) # video file video_relpath = os.path.join('videos', 'video-%s.webm' % time.time()) video_path = os.path.join(outputdir, video_relpath) open(video_path, 'w').write(capture.get_video().read()) # need to initialize dict for product if not there already if not data['testdata'].get(productname): data['testdata'][productname] = {} # app date appdate = appinfo['appdate'] if not data['testdata'][productname].get(appdate): data['testdata'][productname][appdate] = []
def runtest(device_prefs, testname, options, apk=None, appname=None, appdate=None): if apk: appinfo = eideticker.get_fennec_appinfo(apk) appname = appinfo['appname'] print "Installing %s (version: %s, revision %s)" % ( appinfo['appname'], appinfo['version'], appinfo['revision']) device = eideticker.getDevice(**device_prefs) device.updateApp(apk) else: appinfo = None testinfo = eideticker.get_testinfo(testname) stableframecapture = (testinfo['type'] in ('startup', 'webstartup') or testinfo['defaultMeasure'] == 'timetostableframe') capture_results = [] if options.prepare_test: eideticker.prepare_test(testname, device_prefs, options.wifi_settings_file) for i in range(options.num_runs): # Now run the test curtime = int(time.time()) capture_file = os.path.join( CAPTURE_DIR, "metric-test-%s-%s.zip" % (appname, curtime)) if options.enable_profiling and options.outputdir: profile_relpath = os.path.join('profiles', 'sps-profile-%s.zip' % time.time()) profile_file = os.path.join(options.outputdir, profile_relpath) else: profile_file = None current_date = time.strftime("%Y-%m-%d") capture_name = "%s - %s (taken on %s)" % (testname, appname, current_date) testlog = eideticker.run_test( testname, options.capture_device, appname, capture_name, device_prefs, extra_prefs=options.extra_prefs, extra_env_vars=options.extra_env_vars, log_checkerboard_stats=options.get_internal_checkerboard_stats, profile_file=profile_file, capture_area=options.capture_area, camera_settings_file=options.camera_settings_file, capture=options.capture, fps=options.fps, capture_file=capture_file, wifi_settings_file=options.wifi_settings_file, sync_time=options.sync_time, use_vpxenc=options.use_vpxenc) capture_uuid = uuid.uuid1().hex datapoint = {'uuid': capture_uuid} metadata = {} metrics = {} if options.capture: capture = videocapture.Capture(capture_file) datapoint['captureFile'] = metadata['captureFile'] = capture_file metadata['captureFPS'] = capture.fps metadata['generatedVideoFPS'] = capture.generated_video_fps if stableframecapture: metrics['timetostableframe'] = \ eideticker.get_stable_frame_time(capture) else: metrics.update( eideticker.get_standard_metrics(capture, testlog.actions)) metadata['metrics'] = metrics metadata.update(eideticker.get_standard_metric_metadata(capture)) if options.outputdir: # video video_relpath = os.path.join('videos', 'video-%s.webm' % time.time()) video_path = os.path.join(options.outputdir, video_relpath) open(video_path, 'w').write(capture.get_video().read()) metadata['video'] = video_relpath if options.get_internal_checkerboard_stats: metrics['internalcheckerboard'] = \ testlog.checkerboard_percent_totals # Want metrics data in data, so we can graph everything at once datapoint.update(metrics) if options.enable_profiling: metadata['profile'] = profile_file # dump metadata if options.outputdir: # metadata metadata_path = os.path.join(options.outputdir, 'metadata', '%s.json' % capture_uuid) open(metadata_path, 'w').write(json.dumps(metadata)) capture_results.append(datapoint) if options.devicetype == "b2g": # FIXME: get information from sources.xml and application.ini on # device, as we do in update-dashboard.py display_key = appkey = "FirefoxOS" else: appkey = appname if appdate: appkey = appdate.isoformat() else: appkey = appname if appinfo and appinfo.get('revision'): display_key = "%s (%s)" % (appkey, appinfo['revision']) else: display_key = appkey print "=== Results on %s for %s ===" % (testname, display_key) if options.capture: measures = [ ('timetostableframe', 'Times to first stable frame (seconds)'), ('uniqueframes', 'Number of unique frames'), ('fps', 'Average number of unique frames per second'), ('overallentropy', 'Overall entropy over length of capture'), ('checkerboard', 'Checkerboard area/duration (sum of percents NOT ' 'percentage)'), ('timetoresponse', 'Time to first input response (seconds)') ] for measure in measures: if capture_results[0].get(measure[0]): print " %s:" % measure[1] print " %s" % map(lambda c: c[measure[0]], capture_results) print print " Capture files:" print " Capture files: %s" % map(lambda c: c['captureFile'], capture_results) print if options.get_internal_checkerboard_stats: print " Internal Checkerboard Stats (sum of percents, not " "percentage):" print " %s" % map(lambda c: c['internalcheckerboard'], capture_results) print if options.outputdir: outputfile = os.path.join(options.outputdir, "metric.json") resultdict = {'title': testname, 'data': {}} if os.path.isfile(outputfile): resultdict.update(json.loads(open(outputfile).read())) if not resultdict['data'].get(appkey): resultdict['data'][appkey] = [] resultdict['data'][appkey].extend(capture_results) with open(outputfile, 'w') as f: f.write(json.dumps(resultdict))
def main(args=sys.argv[1:]): usage = "usage: %prog [options] <app name>" parser = eideticker.CaptureOptionParser(usage=usage, capture_area_option=False) parser.add_option("--no-capture", action="store_true", dest="no_capture", help="run through the test, but don't actually " "capture anything") parser.add_option("--capture-file", action="store", type="string", dest="capture_file", help="Existing capture to analyze instead of running " "test") parser.add_option("--app-name", action="store", type="string", dest="appname", default="org.mozilla.fennec", help="Specify an application name (android only)") parser.add_option("--output-file", action="store", type="string", dest="output_file", help="Output the results to file") parser.add_option("--output-screenshot", action="store", type="string", dest="output_screenshot", help="Output screenshot of a capture frame with capture " "area overlayed") options, args = parser.parse_args() capture_file = options.capture_file if not capture_file: if not options.no_capture: capture_file = os.path.join(CAPTURE_DIR, "capture-test-%s.zip" % time.time()) print "Capturing to file %s" % capture_file run_capture(options, capture_file) if options.no_capture: # we were just doing a test run through the steps here, we're done return print "Processing capture..." capture = videocapture.Capture(capture_file) result_queue = multiprocessing.Queue() def _get_biggest_framediff_square(result_queue, capture, framenum): imgarray = videocapture.get_framediff_imgarray(capture, framenum - 2, framenum) biggest = square.get_biggest_square([255, 0, 0], imgarray, x_tolerance_min=100, x_tolerance_max=100, handle_multiple_scanlines=True) if biggest: result_queue.put(biggest) multiprocesses = [] for (i, framenum) in enumerate(range(4, capture.num_frames)): p = multiprocessing.Process(target=_get_biggest_framediff_square, args=(result_queue, capture, framenum)) p.start() multiprocesses.append(p) if len(multiprocesses) == 8: for p in multiprocesses: p.join() multiprocesses = [] for p in multiprocesses: p.join() largest_square = None while not result_queue.empty(): s = result_queue.get() if not largest_square or square.get_area(s) > square.get_area( largest_square): largest_square = s if largest_square is not None: print "Capture area: %s" % largest_square if options.output_file: with open(options.output_file, 'w+') as f: f.write('CAPTURE_AREA=%s\n' % largest_square) if options.output_screenshot: im = capture.get_frame_image(int(capture.length / 2)) draw = ImageDraw.Draw(im) draw.rectangle(largest_square, outline=(255, 0, 0)) im.save(options.output_screenshot) else: print "Couldn't find capture area"
def runtest(dm, product, current_date, appname, appinfo, test, capture_name, outputdir, datafile, data, enable_profiling=False, dmtype="adb", host=None, port=None): capture_file = os.path.join( CAPTURE_DIR, "%s-%s-%s-%s.zip" % (test['name'], appname, appinfo.get('date'), int(time.time()))) if enable_profiling: profile_package = os.path.join( CAPTURE_DIR, "profile-package-%s-%s-%s-%s.zip" % (test['name'], appname, appinfo.get('date'), int(time.time()))) urlparams = test.get('urlparams', '') test_completed = False for i in range(3): print "Running test (try %s of 3)" % (i + 1) # Kill any existing instances of the processes before starting dm.killProcess(appname) args = [ "runtest.py", "--url-params", urlparams, "--name", capture_name, "--capture-file", capture_file ] if test.get('startup_test'): args.append("--startup-test") if dmtype: args.extend(["-m", dmtype]) if host: args.extend(["--host", host]) if port: args.extend(["--port", port]) if enable_profiling: args.extend(["--profile-file", profile_package]) retval = subprocess.call(args + [appname, test['path']]) if retval == 0: test_completed = True break else: print "Test failed, retrying..." if not test_completed: raise Exception("Failed to run test %s for %s (after 3 tries). " "Aborting." % (test['name'], product['name'])) capture = videocapture.Capture(capture_file) # video file video_path = os.path.join('videos', 'video-%s.webm' % time.time()) video_file = os.path.join(outputdir, video_path) open(video_file, 'w').write(capture.get_video().read()) # profile file if enable_profiling: profile_path = os.path.join('profiles', 'sps-profile-%s.zip' % time.time()) profile_file = os.path.join(outputdir, profile_path) symbolicated_profile_path = symbolicate_profile_package( profile_package, profile_path, profile_file) os.remove(profile_package) # need to initialize dict for product if not there already if not data[test['name']].get(product['name']): data[test['name']][product['name']] = {} if not data[test['name']][product['name']].get(current_date): data[test['name']][product['name']][current_date] = [] datapoint = { 'uuid': uuid.uuid1().hex, 'video': video_path, 'appdate': appinfo.get('date'), 'buildid': appinfo.get('buildid'), 'revision': appinfo.get('revision') } if test.get('startup_test'): datapoint['timetostableframe'] = videocapture.get_stable_frame_time( capture) else: # standard test metrics datapoint['uniqueframes'] = videocapture.get_num_unique_frames(capture) datapoint['fps'] = videocapture.get_fps(capture) datapoint[ 'checkerboard'] = videocapture.get_checkerboarding_area_duration( capture) if enable_profiling: datapoint['profile'] = symbolicated_profile_path data[test['name']][product['name']][current_date].append(datapoint) # Write the data to disk immediately (so we don't lose it if we fail later) with open(datafile, 'w') as f: f.write(json.dumps(data))
#!/usr/bin/env python # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. import optparse import os import sys import videocapture usage = "usage: %prog [options] <capture file>" parser = optparse.OptionParser(usage) options, args = parser.parse_args() if len(args) <> 1: parser.error("incorrect number of arguments") capture = videocapture.Capture(args[0]) (uniques, processed) = videocapture.get_unique_frames(capture, thresehold=25000) print "Unique frames: %s/%s" % (uniques, processed)
def run_test(device, outputdir, outputfile, test, url_params, num_runs, startup_test, no_capture, get_internal_checkerboard_stats, apk=None, appname=None, appdate=None, profile_file=None, dmtype="adb", host=None, port=None): if apk: appinfo = eideticker.get_fennec_appinfo(apk) appname = appinfo['appname'] print "Installing %s (version: %s, revision %s)" % ( appinfo['appname'], appinfo['version'], appinfo['revision']) device.updateApp(apk) else: appinfo = None captures = [] for i in range(num_runs): # Kill any existing instances of the processes device.killProcess(appname) # Now run the test capture_file = os.path.join( CAPTURE_DIR, "metric-test-%s-%s.zip" % (appname, int(time.time()))) args = ["runtest.py", "--url-params", url_params, appname, test] if get_internal_checkerboard_stats: checkerboard_logfile = tempfile.NamedTemporaryFile() args.extend(["--checkerboard-log-file", checkerboard_logfile.name]) if startup_test: args.extend(["--startup-test"]) if no_capture: args.extend(["--no-capture"]) else: args.extend(["--capture-file", capture_file]) if profile_file: args.extend(["--profile-file", profile_file]) if dmtype: args.extend(["-m", dmtype]) if host: args.extend(["--host", host]) if port: args.extend(["--port", port]) print args retval = subprocess.call(args) if retval != 0: raise Exception("Failed to run test %s for %s" % (test, appname)) capture_result = {} if not no_capture: capture_result['file'] = capture_file capture = videocapture.Capture(capture_file) framediff_sums = videocapture.get_framediff_sums(capture) if startup_test: capture_result['stableframe'] = videocapture.get_stable_frame( capture) else: capture_result[ 'uniqueframes'] = videocapture.get_num_unique_frames( capture) capture_result['fps'] = videocapture.get_fps(capture) capture_result[ 'checkerboard'] = videocapture.get_checkerboarding_area_duration( capture) if outputdir: video_path = os.path.join('videos', 'video-%s.webm' % time.time()) video_file = os.path.join(outputdir, video_path) open(video_file, 'w').write(capture.get_video().read()) capture_result['video'] = video_path if get_internal_checkerboard_stats: internal_checkerboard_totals = parse_checkerboard_log( checkerboard_logfile.name) capture_result[ 'internalcheckerboard'] = internal_checkerboard_totals captures.append(capture_result) appkey = appname if appdate: appkey = appdate.isoformat() else: appkey = appname if appinfo and appinfo.get('revision'): display_key = "%s (%s)" % (appkey, appinfo['revision']) else: display_key = appkey print "=== Results for %s ===" % display_key if not no_capture: if startup_test: print " First stable frames:" print " %s" % map(lambda c: c['stableframe'], captures) print else: print " Number of unique frames:" print " %s" % map(lambda c: c['uniqueframes'], captures) print print " Average number of unique frames per second:" print " %s" % map(lambda c: c['fps'], captures) print print " Checkerboard area/duration (sum of percents NOT percentage):" print " %s" % map(lambda c: c['checkerboard'], captures) print print " Capture files (for further reference):" print " Capture files: %s" % map(lambda c: c['file'], captures) print if get_internal_checkerboard_stats: print " Internal Checkerboard Stats (sum of percents, not percentage):" print " %s" % map(lambda c: c['internalcheckerboard'], captures) print if outputfile: resultdict = {'title': test, 'data': {}} if os.path.isfile(outputfile): resultdict.update(json.loads(open(outputfile).read())) if not resultdict['data'].get(appkey): resultdict['data'][appkey] = [] resultdict['data'][appkey].extend(captures) with open(outputfile, 'w') as f: f.write(json.dumps(resultdict))
def main(args=sys.argv[1:]): usage = "usage: %prog [options] <app name>" parser = eideticker.CaptureOptionParser(usage=usage, capture_area_option=False) parser.add_option("--no-capture", action="store_false", dest="capture", default=True, help="run through the test, but don't actually " "capture anything") parser.add_option("--capture-file", action="store", type="string", dest="capture_file", help="Existing capture to analyze instead of running " "test") parser.add_option("--app-name", action="store", type="string", dest="appname", default="org.mozilla.fennec", help="Specify an application name (android only)") parser.add_option("--output-file", action="store", type="string", dest="output_file", help="Output the results to file") parser.add_option("--output-screenshot", action="store", type="string", dest="output_screenshot", help="Output screenshot of a capture frame with capture " "area overlayed") options, args = parser.parse_args() capture_file = options.capture_file if not capture_file: if options.capture: capture_file = os.path.join(CAPTURE_DIR, "capture-test-%s.zip" % time.time()) print "Capturing to file %s" % capture_file run_capture(options, capture_file) if not options.capture: # we were just doing a test run through the steps here, we're done return print "Processing capture..." capture = videocapture.Capture(capture_file) # create a difference. threshold differences above 32 to 255, then # run our existing algorithm on it framediff = capture.get_frame(0) - capture.get_frame(capture.num_frames - 1) for y, row in enumerate(framediff): for x, px in enumerate(row): if px[0] > 32 or px[1] > 32 or px[2] > 32: framediff[y][x] = [255.0, 255.0, 255.0] largest_square = square.get_biggest_square([255, 255, 255], framediff, x_tolerance_min=100, x_tolerance_max=100, handle_multiple_scanlines=True) if largest_square is not None: print "Capture area: %s" % largest_square if options.output_file: with open(options.output_file, 'w+') as f: f.write('CAPTURE_AREA=%s\n' % largest_square) if options.output_screenshot: im = capture.get_frame_image(int(capture.length / 2)) draw = ImageDraw.Draw(im) draw.rectangle(largest_square, outline=(255, 0, 0)) im.save(options.output_screenshot) else: print "Couldn't find capture area" sys.exit(1)
def GET(self, name): capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name)) return videocapture.get_framediff_sums(capture)