Update MpdGenerator to allow inject version for testing

- Add command line flag --test_packager_version to inject packager
  version; packager_main.cc is also updated to use the same flag.
- Also add a MpdGenerator test in packager_test.py.

Change-Id: I9a11a0ee5502ba30a8acc4d44ebbfaabbe0f2f6e
This commit is contained in:
KongQun Yang 2018-05-30 13:16:30 -07:00
parent 951fedaf41
commit fe944f0656
7 changed files with 107 additions and 22 deletions

View File

@ -24,6 +24,9 @@
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
DEFINE_bool(licenses, false, "Dump licenses."); DEFINE_bool(licenses, false, "Dump licenses.");
DEFINE_string(test_packager_version,
"",
"Packager version for testing. Should be used for testing only.");
namespace shaka { namespace shaka {
namespace { namespace {
@ -117,6 +120,9 @@ int MpdMain(int argc, char** argv) {
return status; return status;
} }
if (!FLAGS_test_packager_version.empty())
SetPackagerVersionForTesting(FLAGS_test_packager_version);
return RunMpdGenerator(); return RunMpdGenerator();
} }

View File

@ -44,15 +44,9 @@ DEFINE_bool(use_fake_clock_for_muxer,
"Set to true to use a fake clock for muxer. With this flag set, " "Set to true to use a fake clock for muxer. With this flag set, "
"creation time and modification time in outputs are set to 0. " "creation time and modification time in outputs are set to 0. "
"Should only be used for testing."); "Should only be used for testing.");
DEFINE_bool(override_version, DEFINE_string(test_packager_version,
false,
"Override packager version in the generated outputs with "
"--test_version if it is set to true. Should be used for "
"testing only.");
DEFINE_string(test_version,
"", "",
"Packager version for testing. Ignored if --override_version is " "Packager version for testing. Should be used for testing only.");
"false. Should be used for testing only.");
namespace shaka { namespace shaka {
namespace { namespace {
@ -441,8 +435,8 @@ base::Optional<PackagingParams> GetPackagingParams() {
TestParams& test_params = packaging_params.test_params; TestParams& test_params = packaging_params.test_params;
test_params.dump_stream_info = FLAGS_dump_stream_info; test_params.dump_stream_info = FLAGS_dump_stream_info;
test_params.inject_fake_clock = FLAGS_use_fake_clock_for_muxer; test_params.inject_fake_clock = FLAGS_use_fake_clock_for_muxer;
if (FLAGS_override_version) if (!FLAGS_test_packager_version.empty())
test_params.injected_library_version = FLAGS_test_version; test_params.injected_library_version = FLAGS_test_packager_version;
return packaging_params; return packaging_params;
} }

View File

@ -5,7 +5,7 @@
# Use of this source code is governed by a BSD-style # Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at # license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd # https://developers.google.com/open-source/licenses/bsd
"""Test wrapper for the sample packager binary.""" """Test wrapper for the sample packager binaries."""
import os import os
import platform import platform
@ -15,18 +15,24 @@ import test_env
class PackagerApp(object): class PackagerApp(object):
"""Main integration class for testing the packager binary.""" """Main integration class for testing the packager binaries."""
def __init__(self): def __init__(self):
packager_name = 'packager' self.packager_binary = os.path.join(test_env.SCRIPT_DIR,
if platform.system() == 'Windows': self._GetBinaryName('packager'))
packager_name += '.exe' self.mpd_generator_binary = os.path.join(
self.binary = os.path.join(test_env.SCRIPT_DIR, packager_name) test_env.SCRIPT_DIR, self._GetBinaryName('mpd_generator'))
# Set this to empty for now in case GetCommandLine() is called before # Set this to empty for now in case GetCommandLine() is called before
# Package(). # Package().
self.packaging_command_line = '' self.packaging_command_line = ''
assert os.path.exists(self.binary), ('Please run from output directory, ' assert os.path.exists(
'e.g. out/Debug/packager_test.py') self.packager_binary), ('Please run from output directory, '
'e.g. out/Debug/packager_test.py')
def _GetBinaryName(self, name):
if platform.system() == 'Windows':
name += '.exe'
return name
def GetEnv(self): def GetEnv(self):
env = os.environ.copy() env = os.environ.copy()
@ -37,18 +43,18 @@ class PackagerApp(object):
def DumpStreamInfo(self, stream): def DumpStreamInfo(self, stream):
input_str = 'input=%s' % stream input_str = 'input=%s' % stream
cmd = [self.binary, input_str, '--dump_stream_info'] cmd = [self.packager_binary, input_str, '--dump_stream_info']
return subprocess.check_output(cmd, env=self.GetEnv()) return subprocess.check_output(cmd, env=self.GetEnv())
def Version(self): def Version(self):
return subprocess.check_output( return subprocess.check_output(
[self.binary, '--version'], env=self.GetEnv()) [self.packager_binary, '--version'], env=self.GetEnv())
def Package(self, streams, flags=None): def Package(self, streams, flags=None):
"""Executes packager command.""" """Executes packager command."""
if flags is None: if flags is None:
flags = [] flags = []
cmd = [self.binary] cmd = [self.packager_binary]
cmd.extend(streams) cmd.extend(streams)
cmd.extend(flags) cmd.extend(flags)
@ -67,3 +73,15 @@ class PackagerApp(object):
def GetCommandLine(self): def GetCommandLine(self):
return self.packaging_command_line return self.packaging_command_line
def MpdGenerator(self, flags):
"""Executes MPD Generator command."""
cmd = [self.mpd_generator_binary]
cmd.extend(flags)
if test_env.options.v:
cmd.extend(['--v=%s' % test_env.options.v])
if test_env.options.vmodule:
cmd.extend(['--vmodule="%s"' % test_env.options.vmodule])
return subprocess.call(cmd, env=self.GetEnv())

View File

@ -378,7 +378,7 @@ class PackagerAppTest(unittest.TestCase):
flags.append('--use_fake_clock_for_muxer') flags.append('--use_fake_clock_for_muxer')
# Override packager version string for testing. # Override packager version string for testing.
flags += ['--override_version', '--test_version', '<tag>-<hash>-<test>'] flags += ['--test_packager_version', '<tag>-<hash>-<test>']
return flags return flags
def _CompareWithGold(self, test_output, golden_file_name): def _CompareWithGold(self, test_output, golden_file_name):
@ -519,6 +519,14 @@ class PackagerFunctionalTest(PackagerAppTest):
def assertPackageSuccess(self, streams, flags=None): def assertPackageSuccess(self, streams, flags=None):
self.assertEqual(self.packager.Package(streams, flags), 0) self.assertEqual(self.packager.Package(streams, flags), 0)
def assertMpdGeneratorSuccess(self):
media_infos = glob.glob(os.path.join(self.tmp_dir, '*.media_info'))
self.assertTrue(media_infos)
flags = ['--input', ','.join(media_infos), '--output', self.mpd_output]
flags += ['--test_packager_version', '<tag>-<hash>-<test>']
self.assertEqual(self.packager.MpdGenerator(flags), 0)
def testVersion(self): def testVersion(self):
self.assertRegexpMatches( self.assertRegexpMatches(
self.packager.Version(), '^packager(.exe)? version ' self.packager.Version(), '^packager(.exe)? version '
@ -1278,6 +1286,16 @@ class PackagerFunctionalTest(PackagerAppTest):
self._GetFlags(encryption=True, output_media_info=True)) self._GetFlags(encryption=True, output_media_info=True))
self._CheckTestResults('encryption-and-output-media-info') self._CheckTestResults('encryption-and-output-media-info')
def testEncryptionAndOutputMediaInfoAndMpdFromMediaInfo(self):
self.assertPackageSuccess(
# The order is not determinstic if there are more than one
# AdaptationSets, so only one is included here.
self._GetStreams(['video']),
self._GetFlags(encryption=True, output_media_info=True))
self.assertMpdGeneratorSuccess()
self._CheckTestResults(
'encryption-and-output-media-info-and-mpd-from-media-info')
def testHlsSingleSegmentMp4Encrypted(self): def testHlsSingleSegmentMp4Encrypted(self):
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], hls=True), self._GetStreams(['audio', 'video'], hls=True),

View File

@ -0,0 +1,31 @@
bandwidth: 977743
video_info {
codec: "avc1.64001e"
width: 640
height: 360
time_scale: 30000
frame_duration: 1001
decoder_config: "\001d\000\036\377\341\000\031gd\000\036\254\331@\240/\371p\021\000\000\003\003\351\000\000\352`\017\026-\226\001\000\006h\353\343\313\"\300"
pixel_width: 1
pixel_height: 1
}
init_range {
begin: 0
end: 1090
}
index_range {
begin: 1091
end: 1158
}
media_file_name: "bear-640x360-video.mp4"
media_duration_seconds: 2.73606658
reference_time_scale: 30000
container_type: CONTAINER_MP4
protected_content {
default_key_id: "1234567890123456"
content_protection_entry {
uuid: "1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"
pssh: "\000\000\0004pssh\001\000\000\000\020w\357\354\300\262M\002\254\343<\036R\342\373K\000\000\000\0011234567890123456\000\000\000\000"
}
protection_scheme: "cenc"
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT0S">
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" par="16:9">
<Representation id="0" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</ContentProtection>
<BaseURL>bear-640x360-video.mp4</BaseURL>
<SegmentBase indexRange="1091-1158" timescale="30000">
<Initialization range="0-1090"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>