tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

generate-config-change-tests.py (9595B)


      1 #!/usr/bin/python
      2 # Copyright (C) 2013 Google Inc. All rights reserved.
      3 #
      4 # Redistribution and use in source and binary forms, with or without
      5 # modification, are permitted provided that the following conditions are
      6 # met:
      7 #
      8 #     * Redistributions of source code must retain the above copyright
      9 # notice, this list of conditions and the following disclaimer.
     10 #     * Redistributions in binary form must reproduce the above
     11 # copyright notice, this list of conditions and the following disclaimer
     12 # in the documentation and/or other materials provided with the
     13 # distribution.
     14 #     * Neither the name of Google Inc. nor the names of its
     15 # contributors may be used to endorse or promote products derived from
     16 # this software without specific prior written permission.
     17 #
     18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 """
     31 This is a script that generates the content and HTML files for Media Source
     32 codec config change LayoutTests.
     33 """
     34 import json
     35 import os
     36 
     37 DURATION = 2
     38 MEDIA_FORMATS = ['webm', 'mp4']
     39 ENCODE_SETTINGS = [
     40    ## Video-only files
     41    # Frame rate changes
     42    {'fs': '320x240', 'fr': 24, 'kfr': 8, 'c': '#ff0000', 'vbr': 128, 'abr': 0, 'asr': 0, 'ach': 0, 'afreq': 0},
     43    {'fs': '320x240', 'fr': 30, 'kfr': 10, 'c': '#ff0000', 'vbr': 128, 'abr': 0, 'asr': 0, 'ach': 0, 'afreq': 0},
     44    # Frame size change
     45    {'fs': '640x480', 'fr': 30, 'kfr': 10, 'c': '#00ff00', 'vbr': 128, 'abr': 0, 'asr': 0, 'ach': 0, 'afreq': 0},
     46    # Bitrate change
     47    {'fs': '320x240', 'fr': 30, 'kfr': 10, 'c': '#ff00ff', 'vbr': 256, 'abr': 0, 'asr': 0, 'ach': 0, 'afreq': 0},
     48 
     49    ## Audio-only files
     50    # Bitrate/Codebook changes
     51    {'fs': '0x0', 'fr': 0, 'kfr': 0, 'c': '#000000', 'vbr': 0, 'abr': 128, 'asr': 44100, 'ach': 1, 'afreq': 2000},
     52    {'fs': '0x0', 'fr': 0, 'kfr': 0, 'c': '#000000', 'vbr': 0, 'abr': 192, 'asr': 44100, 'ach': 1, 'afreq': 4000},
     53 
     54    ## Audio-Video files
     55    # Frame size change.
     56    {'fs': '320x240', 'fr': 30, 'kfr': 10, 'c': '#ff0000', 'vbr': 256, 'abr': 128, 'asr': 44100, 'ach': 1, 'afreq': 2000},
     57    {'fs': '640x480', 'fr': 30, 'kfr': 10, 'c': '#00ff00', 'vbr': 256, 'abr': 128, 'asr': 44100, 'ach': 1, 'afreq': 2000},
     58    # Audio bitrate change.
     59    {'fs': '640x480', 'fr': 30, 'kfr': 10, 'c': '#00ff00', 'vbr': 256, 'abr': 192, 'asr': 44100, 'ach': 1, 'afreq': 4000},
     60    # Video bitrate change.
     61    {'fs': '640x480', 'fr': 30, 'kfr': 10, 'c': '#00ffff', 'vbr': 512, 'abr': 128, 'asr': 44100, 'ach': 1, 'afreq': 2000},
     62 ]
     63 
     64 CONFIG_CHANGE_TESTS = [
     65    ["v-framerate", 0, 1, "Tests %s video-only frame rate changes."],
     66    ["v-framesize", 1, 2, "Tests %s video-only frame size changes."],
     67    ["v-bitrate", 1, 3, "Tests %s video-only bitrate changes."],
     68    ["a-bitrate", 4, 5, "Tests %s audio-only bitrate changes."],
     69    ["av-framesize", 6, 7, "Tests %s frame size changes in multiplexed content."],
     70    ["av-audio-bitrate", 7, 8, "Tests %s audio bitrate changes in multiplexed content."],
     71    ["av-video-bitrate", 7, 9, "Tests %s video bitrate changes in multiplexed content."]
     72 ]
     73 
     74 CODEC_INFO = {
     75    "mp4": {"audio": "mp4a.40.2", "video": "avc1.4D4001"},
     76    "webm": {"audio": "vorbis", "video": "vp8"}
     77 }
     78 
     79 HTML_TEMPLATE = """<!DOCTYPE html>
     80 <html>
     81    <head>
     82        <script src="/w3c/resources/testharness.js"></script>
     83        <script src="/w3c/resources/testharnessreport.js"></script>
     84        <script src="mediasource-util.js"></script>
     85        <script src="mediasource-config-changes.js"></script>
     86    </head>
     87    <body>
     88        <div id="log"></div>
     89        <script>
     90            mediaSourceConfigChangeTest("%(media_format)s", "%(idA)s", "%(idB)s", "%(description)s");
     91        </script>
     92    </body>
     93 </html>
     94 """
     95 
     96 def run(cmd_line):
     97    os.system(" ".join(cmd_line))
     98 
     99 def generate_manifest(filename, media_filename, media_format, has_audio, has_video):
    100    major_type = "audio"
    101    if has_video:
    102        major_type = "video"
    103 
    104    codecs = []
    105    if has_video:
    106        codecs.append(CODEC_INFO[media_format]["video"])
    107 
    108    if has_audio:
    109        codecs.append(CODEC_INFO[media_format]["audio"])
    110 
    111    mimetype = "%s/%s;codecs=\"%s\"" % (major_type, media_format, ",".join(codecs))
    112 
    113    manifest = { 'url': media_filename, 'type': mimetype}
    114 
    115    f = open(filename, "wb")
    116    f.write(json.dumps(manifest, indent=4, separators=(',', ': ')))
    117    f.close()
    118 
    119 def generate_test_html(media_format, config_change_tests, encoding_ids):
    120    for test_info in config_change_tests:
    121        filename = "../../media-source/mediasource-config-change-%s-%s.html" % (media_format, test_info[0])
    122        html = HTML_TEMPLATE % {'media_format': media_format,
    123                                 'idA': encoding_ids[test_info[1]],
    124                                 'idB': encoding_ids[test_info[2]],
    125                                 'description':  test_info[3] % (media_format)}
    126        f = open(filename, "wb")
    127        f.write(html)
    128        f.close()
    129 
    130 
    131 def main():
    132    encoding_ids = []
    133 
    134    for media_format in MEDIA_FORMATS:
    135        run(["mkdir ", media_format])
    136 
    137        for settings in ENCODE_SETTINGS:
    138            video_bitrate = settings['vbr']
    139            has_video = (video_bitrate > 0)
    140 
    141            audio_bitrate = settings['abr']
    142            has_audio = (audio_bitrate > 0)
    143            bitrate = video_bitrate + audio_bitrate
    144 
    145            frame_size = settings['fs']
    146            frame_rate = settings['fr']
    147            keyframe_rate = settings['kfr']
    148            color = settings['c']
    149 
    150            sample_rate = settings['asr']
    151            channels = settings['ach']
    152            frequency = settings['afreq']
    153 
    154            cmdline = ["ffmpeg", "-y"]
    155 
    156            id_prefix = ""
    157            id_params = ""
    158            if has_audio:
    159                id_prefix += "a"
    160                id_params += "-%sHz-%sch" % (sample_rate, channels)
    161 
    162                channel_layout = "FC"
    163                sin_func = "sin(%s*2*PI*t)" % frequency
    164                func = sin_func
    165                if channels == 2:
    166                    channel_layout += "|BC"
    167                    func += "|" + sin_func
    168 
    169                cmdline += ["-f", "lavfi", "-i", "aevalsrc=\"%s:s=%s:c=%s:d=%s\"" % (func, sample_rate, channel_layout, DURATION)]
    170 
    171            if has_video:
    172                id_prefix += "v"
    173                id_params += "-%s-%sfps-%skfr" % (frame_size, frame_rate, keyframe_rate)
    174 
    175                cmdline += ["-f", "lavfi", "-i", "color=%s:duration=%s:size=%s:rate=%s" % (color, DURATION, frame_size, frame_rate)]
    176 
    177            if has_audio:
    178                cmdline += ["-b:a", "%sk" % audio_bitrate]
    179 
    180            if has_video:
    181                cmdline += ["-b:v", "%sk" % video_bitrate]
    182                cmdline += ["-keyint_min", "%s" % keyframe_rate]
    183                cmdline += ["-g", "%s" % keyframe_rate]
    184 
    185 
    186                textOverlayInfo = "'drawtext=fontfile=Mono:fontsize=32:text=Time\\\\:\\\\ %{pts}"
    187                textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=32:text=Size\\\\:\\\\ %s" % (frame_size)
    188                textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=64:text=Bitrate\\\\:\\\\ %s" % (bitrate)
    189                textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=96:text=FrameRate\\\\:\\\\ %s" % (frame_rate)
    190                textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=128:text=KeyFrameRate\\\\:\\\\ %s" % (keyframe_rate)
    191 
    192                if has_audio:
    193                    textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=160:text=SampleRate\\\\:\\\\ %s" % (sample_rate)
    194                    textOverlayInfo += ",drawtext=fontfile=Mono:fontsize=32:y=192:text=Channels\\\\:\\\\ %s" % (channels)
    195 
    196                textOverlayInfo += "'"
    197                cmdline += ["-vf", textOverlayInfo]
    198 
    199            encoding_id = "%s-%sk%s" % (id_prefix, bitrate, id_params)
    200 
    201            if len(encoding_ids) < len(ENCODE_SETTINGS):
    202                encoding_ids.append(encoding_id)
    203 
    204            filename_base = "%s/test-%s" % (media_format, encoding_id)
    205            media_filename = filename_base + "." + media_format
    206            manifest_filename = filename_base + "-manifest.json"
    207 
    208            cmdline.append(media_filename)
    209            run(cmdline)
    210 
    211            # Remux file so it conforms to MSE bytestream requirements.
    212            if media_format == "webm":
    213                tmp_filename = media_filename + ".tmp"
    214                run(["mse_webm_remuxer", media_filename, tmp_filename])
    215                run(["mv", tmp_filename, media_filename])
    216            elif media_format == "mp4":
    217                run(["MP4Box", "-dash", "250", "-rap", media_filename])
    218                run(["mv", filename_base + "_dash.mp4", media_filename])
    219                run(["rm", filename_base + "_dash.mpd"])
    220 
    221            generate_manifest(manifest_filename, media_filename, media_format, has_audio, has_video)
    222        generate_test_html(media_format, CONFIG_CHANGE_TESTS, encoding_ids)
    223 
    224 if '__main__' == __name__:
    225    main()