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()
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))
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))
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))
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)
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]))
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)
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
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))
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
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'))
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
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
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)
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)
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))
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)
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))
def testBrokenName(self): with self.assertRaises(Exception): encoder.Videofile('no_numbers_here.yuv')
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)
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)