def test_OptimizeOverMultipleEncoders(self):
        """Run the optimizer for a few cycles with a real codec.

    This may turn out to be an over-heavy test for every-checkin testing."""
        my_fileset = test_tools.TestFileSet()
        my_codec = vp8.Vp8Codec()
        my_optimizer = optimizer.Optimizer(
            my_codec, my_fileset, cache_class=encoder.EncodingDiskCache)
        # Establish a baseline.
        for bitrate, videofile_name in my_fileset.AllFilesAndRates():
            videofile = encoder.Videofile(videofile_name)
            my_encoding = my_optimizer.BestEncoding(bitrate, videofile)
            my_encoding.Execute().Store()
        # Try to improve it.
        encoding_count = 0
        while encoding_count < 10:
            (bitrate,
             videofile_name) = random.choice(my_fileset.AllFilesAndRates())
            videofile = encoder.Videofile(videofile_name)
            next_encoding = my_optimizer.BestUntriedEncoding(
                bitrate, videofile)
            if not next_encoding:
                break
            encoding_count += 1
            next_encoding.Execute().Store()
Exemple #2
0
  def BestOverallEncoder(self):
    """Returns the configuration that is best over all files.

    This looks only at configurations that have been run for every
    file and rate in the fileset."""
    files_and_rates = self.file_set.AllFilesAndRates()
    all_scored_encodings = self.context.cache.AllScoredEncodings(
        files_and_rates[0][0],
        encoder.Videofile(files_and_rates[0][1]))
    candidate_encoder_ids = set([x.encoder.Hashname()
                                for x in all_scored_encodings])
    candidate_encoders = dict([(x.encoder.Hashname(), x.encoder)
                              for x in all_scored_encodings])
    for rate, filename in files_and_rates[1:]:
      these_encoders = set([x.encoder.Hashname()
                            for x in self.context.cache.AllScoredEncodings(
                              rate, encoder.Videofile(filename))])
      candidate_encoder_ids.intersection_update(these_encoders)
    if len(candidate_encoder_ids) == 0:
      return None
    if len(candidate_encoder_ids) == 1:
      return candidate_encoders[candidate_encoder_ids.pop()]
    best_score = -10000
    best_encoder = None
    for hashname in candidate_encoder_ids:
      this_total = 0
      this_encoder = candidate_encoders[hashname]
      for rate, filename in files_and_rates:
        this_encoding = this_encoder.Encoding(rate, encoder.Videofile(filename))
        this_encoding.Recover()
        this_total += self.Score(this_encoding)
      if this_total > best_score:
        best_score = this_total
        best_encoder = this_encoder
    return best_encoder
    def testStoreMultipleEncodings(self):
        context = StorageOnlyContext()
        cache = encoder.EncodingMemoryCache(context)
        # This particular test needs the context to know about the cache.
        context.cache = cache
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)

        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        my_encoding = encoder.Encoding(my_encoder, 246, videofile)
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        result = cache.AllScoredRates(my_encoder, videofile)
        self.assertEquals(2, len(result))
        result = cache.AllScoredEncodings(123, videofile)
        self.assertEquals(1, len(result))
        # Verify that it's working correctly with a new videofile object.
        videofile2 = encoder.Videofile(videofile.filename)
        result = cache.AllScoredEncodings(123, videofile2)
        my_encoding = encoder.Encoding(my_encoder, 123, videofile2)
        self.assertTrue(cache.ReadEncodingResult(my_encoding))
        # Verify that it's working correctly with an encoder created via hashname.
        encoder2 = encoder.Encoder(context, filename=my_encoder.Hashname())
        encoding2 = encoder2.Encoding(123, videofile2)
        self.assertTrue(cache.ReadEncodingResult(encoding2))
Exemple #4
0
 def testEncodersInMultipleRepos(self):
     test_tools.EmptyWorkDirectory()
     context = StorageOnlyContext()
     cache = encoder.EncodingDiskCache(context)
     context.cache = cache
     my_encoder = encoder.Encoder(
         context, encoder.OptionValueSet(encoder.OptionSet(),
                                         '--parameters'))
     other_dir = os.path.join(encoder_configuration.conf.sysdir(),
                              'multirepo_test')
     os.mkdir(other_dir)
     other_cache = encoder.EncodingDiskCache(context,
                                             scoredir='multirepo_test')
     encoder_configuration.conf.override_scorepath_for_test([other_dir])
     other_cache.StoreEncoder(my_encoder)
     encoders = cache.AllEncoderFilenames(only_workdir=True)
     self.assertEquals(0, len(encoders))
     encoders = cache.AllEncoderFilenames(only_workdir=False)
     self.assertEquals(1, len(encoders))
     fetched_encoder = encoder.Encoder(context, filename=encoders[0])
     self.assertEquals(my_encoder.parameters.ToString(),
                       fetched_encoder.parameters.ToString())
     my_encoding = encoder.Encoding(
         my_encoder, 123, encoder.Videofile('x/foo_640_480_20.yuv'))
     testresult = {'foo': 'bar'}
     my_encoding.result = testresult
     other_cache.StoreEncoding(my_encoding)
     # With a specified directory, we should find it in only one place.
     self.assertTrue(other_cache.ReadEncodingResult(my_encoding))
     # Without a specified directory, we should find it on the searchpath.
     self.assertTrue(cache.ReadEncodingResult(my_encoding))
     # Without a searchpath, we shouldn't find it in the default cache.
     encoder_configuration.conf.override_scorepath_for_test([])
     self.assertFalse(cache.ReadEncodingResult(my_encoding))
Exemple #5
0
    def testBrokenStoredEncoding(self):
        context = StorageOnlyContext()
        other_dir = os.path.join(encoder_configuration.conf.sysdir(),
                                 'broken_files')
        os.mkdir(other_dir)

        cache = encoder.EncodingDiskCache(context, scoredir='broken_files')
        # This particular test needs the context to know about the cache.
        context.cache = cache
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        # Cache should start off empty.
        self.assertFalse(cache.AllScoredEncodingsForEncoder(my_encoder))
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)
        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        # TODO(hta): Expose the filename generation as a function for testing.
        with open(
                os.path.join(
                    cache.workdir, my_encoding.encoder.Hashname(),
                    cache.context.codec.SpeedGroup(my_encoding.bitrate),
                    '%s.result' % my_encoding.videofile.basename),
                'w') as scorefile:
            scorefile.write('stuff that is not valid json')

        result = cache.AllScoredEncodingsForEncoder(my_encoder)
        self.assertFalse(result)
        self.assertEquals(1, len(cache.bad_encodings))
Exemple #6
0
    def test_BestOverallConfigurationNotInWorkDirectory(self):
        other_dir = os.path.join(encoder_configuration.conf.sysdir(),
                                 'multirepo_test')
        os.mkdir(other_dir)
        encoder_configuration.conf.override_scorepath_for_test([other_dir])

        self.file_set = optimizer.FileAndRateSet(verify_files_present=False)
        self.file_set.AddFilesAndRates([self.videofile.filename], [100, 200])
        self.optimizer = optimizer.Optimizer(self.codec, self.file_set)
        # When there is nothing in the database, None should be returned.
        best_encoder = self.optimizer.BestOverallEncoder()
        self.assertIsNone(best_encoder)
        # Fill in the database with all the files and rates.
        other_context = encoder.Context(self.codec,
                                        encoder.EncodingDiskCache,
                                        scoredir='multirepo_test')
        my_encoder = self.EncoderFromParameterString('--score=7')
        other_context.cache.StoreEncoder(my_encoder)
        my_encoder.context.cache.StoreEncoder(my_encoder)
        for rate, filename in self.file_set.AllFilesAndRates():
            my_encoding = my_encoder.Encoding(rate,
                                              encoder.Videofile(filename))
            my_encoding.Execute()
            other_context.cache.StoreEncoding(my_encoding)
        # The best encoder should now be from the workdir, but the results are
        # all fetched from the searchpath.
        best_encoder = self.optimizer.BestOverallEncoder()
        self.assertTrue(best_encoder)
        self.assertEquals(my_encoder.parameters.ToString(),
                          best_encoder.parameters.ToString())
        one_encoding = best_encoder.Encoding(100, self.videofile)
        one_encoding.Recover()
        self.assertTrue(one_encoding.Result())
 def test_BestOverallConfiguration(self):
     self.file_set = optimizer.FileAndRateSet(verify_files_present=False)
     self.file_set.AddFilesAndRates([self.videofile.filename], [100, 200])
     my_optimizer = self.StdOptimizer()
     # When there is nothing in the database, None should be returned.
     best_encoder = my_optimizer.BestOverallEncoder()
     self.assertIsNone(best_encoder)
     # Fill in the database with all the files and rates.
     my_encoder = self.EncoderFromParameterString('--score=7')
     for rate, filename in self.file_set.AllFilesAndRates():
         my_encoder.Encoding(rate,
                             encoder.Videofile(filename)).Execute().Store()
     best_encoder = my_optimizer.BestOverallEncoder()
     self.assertTrue(best_encoder)
     self.assertEquals(my_encoder.parameters.ToString(),
                       best_encoder.parameters.ToString())
     # Add an incomplete encode. This should be ignored.
     (self.EncoderFromParameterString('--score=9').Encoding(
         100, self.videofile).Execute().Store())
     best_encoder = my_optimizer.BestOverallEncoder()
     self.assertTrue(best_encoder)
     self.assertEquals(my_encoder.parameters.ToString(),
                       best_encoder.parameters.ToString())
     #  Complete the set for 'score=9'. This should cause a change.
     (self.EncoderFromParameterString('--score=9').Encoding(
         200, self.videofile).Execute().Store())
     best_encoder = my_optimizer.BestOverallEncoder()
     self.assertTrue(best_encoder)
     self.assertEquals('--score=9', best_encoder.parameters.ToString())
    def testReadResultEncodedInAst(self):
        # We've changed the storage format for results from AST to JSON.
        # This test verifies that AST formatted results are still readable.
        context = StorageOnlyContext()
        cache = encoder.EncodingDiskCache(context)
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        my_encoding = encoder.Encoding(
            my_encoder, 123, encoder.Videofile('x/foo_640_480_20.yuv'))
        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        # The following code is a copy of cache.StoreEncoding, with the
        # encoding step changed.
        dirname = '%s/%s/%s' % (cache.workdir, my_encoding.encoder.Hashname(),
                                cache.context.codec.SpeedGroup(
                                    my_encoding.bitrate))
        videoname = my_encoding.videofile.basename
        with open('%s/%s.result' % (dirname, videoname), 'w') as resultfile:
            resultfile.write(str(my_encoding.result))

        my_encoding.result = None
        result = cache.ReadEncodingResult(my_encoding)
        self.assertEquals(result, testresult)
Exemple #9
0
 def test_ListOneTarget(self):
     datatable = {}
     filename = 'file_10x10_10'
     videofile = encoder.Videofile(filename)
     visual_metrics.ListOneTarget([FakeOptimizer()], 1000, videofile, False,
                                  datatable)
     self.assertEquals(1, len(datatable['mock'][filename]))
Exemple #10
0
def ListMpegResults(codecs, do_score, datatable, score_function=None):
    """List all scores for all tests in the MPEG test set for a set of codecs."""
    # It is necessary to sort on target bitrate in order for graphs to display
    # correctly.
    for rate, filename in sorted(mpeg_settings.MpegFiles().AllFilesAndRates()):
        videofile = encoder.Videofile(filename)
        ListOneTarget(codecs, rate, videofile, do_score, datatable,
                      score_function)
Exemple #11
0
def MakeYuvFileWithOneBlankFrame(name):
  """ Make an YUV file with one black frame.
  The size of the frame is encoded in the filename."""
  videofile = encoder.Videofile('%s/%s' % (os.getenv('CODEC_WORKDIR'),
                                           name))
  # Frame size in an YUV 4:2:0 file is 1.5 bytes per pixel.
  framesize = videofile.width * videofile.height * 3 / 2
  with open(videofile.filename, 'w') as real_file:
    real_file.write('\0' * framesize)
  return videofile
def GenerateFilesetFromDirectory(name):
  """Returns a FileAndRateSet containing all the YUV files in the directory."""
  yuvfiles = glob.glob(os.path.join(os.getenv('WORKDIR'),
                                    'video', name, '*.yuv'))
  my_set = optimizer.FileAndRateSet()
  for yuvfile in yuvfiles:
    videofile = encoder.Videofile(yuvfile)
    my_set.AddFilesAndRates([videofile.filename],
                            ChooseRates(videofile.width, videofile.framerate))
  return my_set
Exemple #13
0
 def test_SuggestTweakDecreasesCq(self):
   codec = vp8_cq.Vp8CodecCqMode()
   videofile = encoder.Videofile('foofile_640_480_30.yuv')
   my_encoder = codec.start_encoder
   encoding = encoder.Encoding(my_encoder, 500, videofile)
   encoding.result = { 'bitrate' : 200 }
   # Since the bitrate is too high, the suggstion should be to increase it.
   new_encoding = codec.SuggestTweak(encoding)
   self.assertEqual('31', encoder.Option('min-q').GetValue(
           new_encoding.encoder.parameters))
Exemple #14
0
def MakeYuvFileWithNoisyFrames(name, count):
    """Make an YUV file with one or more frames containing noise."""
    videofile = encoder.Videofile('%s/%s' %
                                  (encoder_configuration.conf.workdir(), name))
    # Frame size in an YUV 4:2:0 file is 1.5 bytes per pixel.
    framesize = videofile.width * videofile.height * 3 / 2
    with open(videofile.filename, 'w') as real_file:
        for frameno in xrange(count):
            for videobyte in xrange(framesize):
                real_file.write(str(chr((frameno + videobyte) % 256)))
    return videofile
Exemple #15
0
 def test_SuggestTweakDecreasesCq(self):
     codec = vp8_mpeg_1d.Vp8CodecMpeg1dMode()
     videofile = encoder.Videofile('foofile_640_480_30.yuv')
     my_optimizer = optimizer.Optimizer(codec)
     my_encoder = codec.StartEncoder(my_optimizer.context)
     encoding = encoder.Encoding(my_encoder, 500, videofile)
     encoding.result = {'bitrate': 200}
     # Since the bitrate is too high, the suggstion should be to increase it.
     new_encoding = codec.SuggestTweak(encoding)
     self.assertEqual('0',
                      new_encoding.encoder.parameters.GetValue('key-q'))
Exemple #16
0
def MakeYuvFileWithBlankFrames(name, count):
    """Make an YUV file with one or more blank frames (all zeroes).

  The size of the frame is encoded in the filename."""
    videofile = encoder.Videofile('%s/%s' %
                                  (encoder_configuration.conf.workdir(), name))
    # Frame size in an YUV 4:2:0 file is 1.5 bytes per pixel.
    framesize = videofile.width * videofile.height * 3 / 2
    with open(videofile.filename, 'w') as real_file:
        real_file.write('\0' * framesize * count)
    return videofile
Exemple #17
0
 def testStoreFetchEncoding(self):
     context = StorageOnlyContext()
     cache = encoder.EncodingDiskCache(context)
     my_encoder = encoder.Encoder(
         context, encoder.OptionValueSet(encoder.OptionSet(),
                                         '--parameters'))
     cache.StoreEncoder(my_encoder)
     my_encoding = encoder.Encoding(
         my_encoder, 123, encoder.Videofile('x/foo_640_480_20.yuv'))
     testresult = {'foo': 'bar'}
     my_encoding.result = testresult
     cache.StoreEncoding(my_encoding)
     my_encoding.result = None
     result = cache.ReadEncodingResult(my_encoding)
     self.assertEquals(result, testresult)
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--codec')
    parser.add_argument('--score', action='store_true', default=False)
    args = parser.parse_args()

    codec = pick_codec.PickCodec(args.codec)
    for classname in mpeg_settings.files.keys():
        for filename in mpeg_settings.files[classname]:
            for rate in mpeg_settings.rates[classname]:
                videofile = encoder.Videofile('../mpeg_video/%s' % filename)
                encoding = codec.BestEncoding(rate, videofile)
                print rate, filename, encoding.Score(), encoding.result
                AnalyzeVariants(encoding, args.score)
    return 0
 def __init__(self, filename, codec, score_function):
     self.name = codec.name
     self.videofile = encoder.Videofile(filename)
     self.fileset = optimizer.FileAndRateSet()
     self.fileset.AddFilesAndRates([filename],
                                   fileset_picker.ChooseRates(
                                       self.videofile.width,
                                       self.videofile.framerate))
     self.my_optimizer = optimizer.Optimizer(codec,
                                             file_set=self.fileset,
                                             score_function=score_function)
     self.filename = filename
     self.encoder = self.my_optimizer.BestOverallEncoder()
     if not self.encoder:
         raise NotEnoughDataError('No overall encoder for %s on %s' %
                                  (codec.name, filename))
     self.points = None
Exemple #20
0
def ListMpegSingleConfigResults(codecs, datatable, score_function=None):
    encoder_list = {}
    optimizer_list = {}
    for codec_name in codecs:
        codec = pick_codec.PickCodec(codec_name)
        my_optimizer = optimizer.Optimizer(codec,
                                           score_function=score_function,
                                           file_set=mpeg_settings.MpegFiles())
        optimizer_list[codec_name] = my_optimizer
        encoder_list[codec_name] = my_optimizer.BestOverallEncoder()
    for rate, filename in sorted(mpeg_settings.MpegFiles().AllFilesAndRates()):
        videofile = encoder.Videofile(filename)
        for codec_name in codecs:
            if encoder_list[codec_name]:
                my_encoding = encoder_list[codec_name].Encoding(
                    rate, videofile)
                my_encoding.Recover()
                AddOneEncoding(codec_name, optimizer_list[codec_name],
                               my_encoding, videofile, datatable)
Exemple #21
0
    def testReadResultFromAlternateDir(self):
        context = StorageOnlyContext()
        otherdir = os.path.join(os.environ['CODEC_WORKDIR'], 'otherdir')
        cache = encoder.EncodingDiskCache(context)
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)

        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        my_encoding.result = None
        result = cache.ReadEncodingResult(my_encoding, scoredir=otherdir)
        self.assertIsNone(result)
        shutil.copytree(os.environ['CODEC_WORKDIR'], otherdir)
        result = cache.ReadEncodingResult(my_encoding, scoredir=otherdir)
        self.assertEquals(result, testresult)
Exemple #22
0
    def testStoreMultipleEncodings(self):
        context = StorageOnlyContext()
        cache = encoder.EncodingMemoryCache(context)
        # This particular test needs the context to know about the cache.
        context.cache = cache
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)

        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        my_encoding = encoder.Encoding(my_encoder, 246, videofile)
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        result = cache.AllScoredRates(my_encoder, videofile)
        self.assertEquals(2, len(result))
        result = cache.AllScoredEncodings(123, videofile)
        self.assertEquals(1, len(result))
Exemple #23
0
 def testAllScoredEncodingsForEncoder(self):
     context = StorageOnlyContext()
     cache = encoder.EncodingDiskCache(context)
     # This particular test needs the context to know about the cache.
     context.cache = cache
     my_encoder = encoder.Encoder(
         context, encoder.OptionValueSet(encoder.OptionSet(),
                                         '--parameters'))
     cache.StoreEncoder(my_encoder)
     # Cache should start off empty.
     self.assertFalse(cache.AllScoredEncodingsForEncoder(my_encoder))
     videofile = encoder.Videofile('x/foo_640_480_20.yuv')
     my_encoding = encoder.Encoding(my_encoder, 123, videofile)
     testresult = {'foo': 'bar'}
     my_encoding.result = testresult
     cache.StoreEncoding(my_encoding)
     result = cache.AllScoredEncodingsForEncoder(my_encoder)
     self.assertTrue(result)
     self.assertEquals(1, len(result))
     # The resulting videofile should have a basename = filename,
     # because synthesizing filenames from result files loses directory
     # information.
     self.assertEquals('foo_640_480_20.yuv', result[0].videofile.filename)
Exemple #24
0
    def testReadResultFromAlternateDir(self):
        context = StorageOnlyContext()
        otherdir_path = os.path.join(encoder_configuration.conf.sysdir(),
                                     'otherdir')
        os.mkdir(otherdir_path)
        cache = encoder.EncodingDiskCache(context)
        other_cache = encoder.EncodingDiskCache(context, scoredir='otherdir')
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)

        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        my_encoding.result = None
        result = other_cache.ReadEncodingResult(my_encoding)
        self.assertIsNone(result)
        shutil.rmtree(otherdir_path)
        shutil.copytree(encoder_configuration.conf.workdir(), otherdir_path)
        result = other_cache.ReadEncodingResult(my_encoding)
        self.assertEquals(result, testresult)
    def testStoreMultipleEncodings(self):
        # This test is sensitive to old data left around.
        # The FileUsingCodecTest base class takes care of giving it an
        # empty directory at test start.
        context = StorageOnlyContext()
        cache = encoder.EncodingDiskCache(context)
        context.cache = cache  # This particular test needs the link.
        my_encoder = encoder.Encoder(
            context, encoder.OptionValueSet(encoder.OptionSet(),
                                            '--parameters'))
        cache.StoreEncoder(my_encoder)
        videofile = encoder.Videofile('x/foo_640_480_20.yuv')
        my_encoding = encoder.Encoding(my_encoder, 123, videofile)

        testresult = {'foo': 'bar'}
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        my_encoding = encoder.Encoding(my_encoder, 246, videofile)
        my_encoding.result = testresult
        cache.StoreEncoding(my_encoding)
        result = cache.AllScoredRates(my_encoder, videofile)
        self.assertEquals(2, len(result))
        result = cache.AllScoredEncodings(123, videofile)
        self.assertEquals(1, len(result))
Exemple #26
0
 def testBrokenName(self):
     with self.assertRaises(Exception):
         encoder.Videofile('no_numbers_here.yuv')
Exemple #27
0
 def testMpegFormatWithTrailer(self):
     videofile = encoder.Videofile('test_640x480_20_part.yuv')
     self.assertEqual(640, videofile.width)
     self.assertEqual(480, videofile.height)
     self.assertEqual(20, videofile.framerate)
Exemple #28
0
 def testGoogleFormatName(self):
     videofile = encoder.Videofile('test_640_480_20.yuv')
     self.assertEqual(640, videofile.width)
     self.assertEqual(480, videofile.height)
     self.assertEqual(20, videofile.framerate)