Example #1
0
    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()
Example #2
0
    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
Example #3
0
 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
     }
Example #4
0
    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()
Example #5
0
    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
Example #6
0
                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))
Example #8
0
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))
Example #10
0
#!/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))
Example #12
0
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)
Example #13
0
 def GET(self, name):
     capture = videocapture.Capture(os.path.join(CAPTURE_DIR, name))
     return videocapture.get_framediff_sums(capture)