Support generation of libpackager.so (shared_library)

Shared libpackager can be built by setting libpackager_type to
shared_library, e.g.

GYP_DEFINES='libpackager_type=shared_library' gclient runhooks
ninja -C out/Debug

will generate libpackager.so in out/Debug/lib directory.

Here is a few other changes to make shared_library builds and
tests pass:

- Add several test parameters to packager.h, which is needed for
  testing.
- Create a protoc.gypi from build/protoc.gypi but depending on
  protobuf_full_do_not_use instead of protobuf_lite, since we need
  protobuf_full_do_not_use for text parsing and generation of media
  info proto. Somehow shared_library build does not allow mixed use
  of protobuf_full_do_not_use and protobuf_lite.
- Remove the use of LazyInstance in version/version.cc and use static
  variable directly. This is because LazyInstance needs AtExitManager
  which may not be easy to setup when calling GetVersion.
- Allow skipping testPackageWvmInputWithoutStrippingParameterSetNalus
  with flag --shared_library, which is needed as shared_library build
  does not support --strip_parameter_set_nalus flag yet.

Fixes #227

Change-Id: Iff05a50baa28134faa7218664c96114cb9e70329
This commit is contained in:
KongQun Yang 2017-05-22 19:41:26 -07:00
parent 2816a7262e
commit 05a5a41969
14 changed files with 323 additions and 67 deletions

View File

@ -17,7 +17,6 @@
#include "packager/app/stream_descriptor.h" #include "packager/app/stream_descriptor.h"
#include "packager/app/vlog_flags.h" #include "packager/app/vlog_flags.h"
#include "packager/app/widevine_encryption_flags.h" #include "packager/app/widevine_encryption_flags.h"
#include "packager/base/at_exit.h"
#include "packager/base/command_line.h" #include "packager/base/command_line.h"
#include "packager/base/logging.h" #include "packager/base/logging.h"
#include "packager/base/optional.h" #include "packager/base/optional.h"
@ -26,7 +25,6 @@
#include "packager/base/strings/stringprintf.h" #include "packager/base/strings/stringprintf.h"
#include "packager/media/file/file.h" #include "packager/media/file/file.h"
#include "packager/packager.h" #include "packager/packager.h"
#include "packager/version/version.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include <codecvt> #include <codecvt>
@ -34,6 +32,12 @@
#include <locale> #include <locale>
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
DEFINE_bool(dump_stream_info, false, "Dump demuxed stream info.");
DEFINE_bool(use_fake_clock_for_muxer,
false,
"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. "
"Should only be used for testing.");
DEFINE_bool(override_version, DEFINE_bool(override_version,
false, false,
"Override packager version in the generated outputs with " "Override packager version in the generated outputs with "
@ -286,11 +290,16 @@ base::Optional<PackagingParams> GetPackagingParams() {
hls_params.master_playlist_output = FLAGS_hls_master_playlist_output; hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
hls_params.base_url = FLAGS_hls_base_url; hls_params.base_url = FLAGS_hls_base_url;
TestParams& test_params = packaging_params.test_params;
test_params.dump_stream_info = FLAGS_dump_stream_info;
test_params.inject_fake_clock = FLAGS_use_fake_clock_for_muxer;
if (FLAGS_override_version)
test_params.injected_library_version = FLAGS_test_version;
return packaging_params; return packaging_params;
} }
int PackagerMain(int argc, char** argv) { int PackagerMain(int argc, char** argv) {
base::AtExitManager exit;
// Needed to enable VLOG/DVLOG through --vmodule or --v. // Needed to enable VLOG/DVLOG through --vmodule or --v.
base::CommandLine::Init(argc, argv); base::CommandLine::Init(argc, argv);
@ -299,7 +308,7 @@ int PackagerMain(int argc, char** argv) {
log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
CHECK(logging::InitLogging(log_settings)); CHECK(logging::InitLogging(log_settings));
google::SetVersionString(GetPackagerVersion()); google::SetVersionString(shaka::ShakaPackager::GetLibraryVersion());
google::SetUsageMessage(base::StringPrintf(kUsage, argv[0])); google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
google::ParseCommandLineFlags(&argc, &argv, true); google::ParseCommandLineFlags(&argc, &argv, true);
if (argc < 2) { if (argc < 2) {
@ -312,9 +321,6 @@ int PackagerMain(int argc, char** argv) {
return kArgumentValidationFailed; return kArgumentValidationFailed;
} }
if (FLAGS_override_version)
SetPackagerVersionForTesting(FLAGS_test_version);
base::Optional<PackagingParams> packaging_params = GetPackagingParams(); base::Optional<PackagingParams> packaging_params = GetPackagingParams();
if (!packaging_params) if (!packaging_params)
return kArgumentValidationFailed; return kArgumentValidationFailed;

View File

@ -9,16 +9,12 @@
#ifndef PACKAGER_APP_PACKAGER_UTIL_H_ #ifndef PACKAGER_APP_PACKAGER_UTIL_H_
#define PACKAGER_APP_PACKAGER_UTIL_H_ #define PACKAGER_APP_PACKAGER_UTIL_H_
#include <gflags/gflags.h>
#include <memory> #include <memory>
#include "packager/base/optional.h" #include "packager/base/optional.h"
#include "packager/media/base/fourccs.h" #include "packager/media/base/fourccs.h"
#include "packager/packager.h" #include "packager/packager.h"
DECLARE_bool(dump_stream_info);
namespace shaka { namespace shaka {
// TODO(kqyang): Should we consolidate XxxParams and XxxOptions? // TODO(kqyang): Should we consolidate XxxParams and XxxOptions?

View File

@ -454,6 +454,13 @@ class PackagerAppTest(unittest.TestCase):
self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4') self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4')
self._DiffGold(self.mpd_output, 'bear-wvm-golden.mpd') self._DiffGold(self.mpd_output, 'bear-wvm-golden.mpd')
# TODO(kqyang): Fix shared_library not supporting strip_parameter_set_nalus
# problem.
@unittest.skipUnless(
test_env.options.static_libpackager,
'libpackager shared_library does not support '
'--strip_parameter_set_nalus flag.'
)
def testPackageWvmInputWithoutStrippingParameterSetNalus(self): def testPackageWvmInputWithoutStrippingParameterSetNalus(self):
self.packager.Package( self.packager.Package(
self._GetStreams( self._GetStreams(

View File

@ -27,6 +27,13 @@ SRC_DIR = os.path.join(SCRIPT_DIR, os.pardir, os.pardir)
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--test_update_golden_files', default=0, type=int) parser.add_argument('--test_update_golden_files', default=0, type=int)
parser.add_argument('--static_libpackager',
dest='static_libpackager', action='store_true')
parser.add_argument('--shared_libpackager',
dest='static_libpackager', action='store_false')
parser.set_defaults(static_libpackager=True)
parser.add_argument('--v') parser.add_argument('--v')
parser.add_argument('--vmodule') parser.add_argument('--vmodule')
# Overwrite the test to encryption key/iv specified in the command line. # Overwrite the test to encryption key/iv specified in the command line.

View File

@ -10,6 +10,7 @@
'variables': { 'variables': {
# Compile as Chromium code to enable warnings and warnings-as-errors. # Compile as Chromium code to enable warnings and warnings-as-errors.
'chromium_code': 1, 'chromium_code': 1,
'libpackager_type%': 'static_library',
}, },
'target_defaults': { 'target_defaults': {
'include_dirs': [ 'include_dirs': [

View File

@ -114,9 +114,8 @@
'proto_in_dir': '.', 'proto_in_dir': '.',
'proto_out_dir': 'packager/media/base', 'proto_out_dir': 'packager/media/base',
}, },
'includes': ['../../build/protoc.gypi'], 'includes': [
'dependencies': [ '../../protoc.gypi',
'../../third_party/protobuf/protobuf.gyp:protobuf_lite',
], ],
}, },
{ {

View File

@ -9,7 +9,9 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <limits> #include <limits>
#include "packager/base/logging.h"
#include "packager/base/strings/string_number_conversions.h" #include "packager/base/strings/string_number_conversions.h"
#include "packager/media/base/buffer_writer.h"
// TODO(kqyang): Move byte to unit stream convertion to muxer and make it a // TODO(kqyang): Move byte to unit stream convertion to muxer and make it a
// muxer option. // muxer option.
@ -21,9 +23,6 @@ DEFINE_bool(strip_parameter_set_nalus,
"frames. Note that avc1/hvc1 is generated if this flag is enabled; " "frames. Note that avc1/hvc1 is generated if this flag is enabled; "
"otherwise avc3/hev1 is generated."); "otherwise avc3/hev1 is generated.");
#include "packager/base/logging.h"
#include "packager/media/base/buffer_writer.h"
namespace shaka { namespace shaka {
namespace media { namespace media {

View File

@ -21,13 +21,7 @@
'proto_in_dir': 'base', 'proto_in_dir': 'base',
'proto_out_dir': 'packager/mpd/base', 'proto_out_dir': 'packager/mpd/base',
}, },
'includes': ['../build/protoc.gypi'], 'includes': ['../protoc.gypi'],
'dependencies': [
# This target needs to depend on 'protobuf_full_do_not_use' to generate
# non-LITE (full) protobuf. We need full protobuf to serialize and
# deserialize human readable protobuf messages.
'../third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
],
}, },
{ {
'target_name': 'mpd_builder', 'target_name': 'mpd_builder',

View File

@ -6,12 +6,10 @@
#include "packager/packager.h" #include "packager/packager.h"
#include <gflags/gflags.h>
#include <iostream>
#include "packager/app/libcrypto_threading.h" #include "packager/app/libcrypto_threading.h"
#include "packager/app/packager_util.h" #include "packager/app/packager_util.h"
#include "packager/app/stream_descriptor.h" #include "packager/app/stream_descriptor.h"
#include "packager/base/at_exit.h"
#include "packager/base/files/file_path.h" #include "packager/base/files/file_path.h"
#include "packager/base/logging.h" #include "packager/base/logging.h"
#include "packager/base/path_service.h" #include "packager/base/path_service.h"
@ -40,13 +38,7 @@
#include "packager/mpd/base/media_info.pb.h" #include "packager/mpd/base/media_info.pb.h"
#include "packager/mpd/base/mpd_builder.h" #include "packager/mpd/base/mpd_builder.h"
#include "packager/mpd/base/simple_mpd_notifier.h" #include "packager/mpd/base/simple_mpd_notifier.h"
#include "packager/version/version.h"
DEFINE_bool(dump_stream_info, false, "Dump demuxed stream info.");
DEFINE_bool(use_fake_clock_for_muxer,
false,
"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. "
"Should only be used for testing.");
namespace shaka { namespace shaka {
@ -124,7 +116,7 @@ bool ValidateStreamDescriptor(bool dump_stream_info,
const bool output_specified = const bool output_specified =
!descriptor.output.empty() || !descriptor.segment_template.empty(); !descriptor.output.empty() || !descriptor.segment_template.empty();
if (!output_specified) { if (!output_specified) {
if (!FLAGS_dump_stream_info) { if (!dump_stream_info) {
LOG(ERROR) << "Stream output not specified."; LOG(ERROR) << "Stream output not specified.";
return false; return false;
} }
@ -201,7 +193,8 @@ bool ValidateParams(const PackagingParams& packaging_params,
"stream descriptors."; "stream descriptors.";
return false; return false;
} }
if (!ValidateStreamDescriptor(FLAGS_dump_stream_info, descriptor)) if (!ValidateStreamDescriptor(packaging_params.test_params.dump_stream_info,
descriptor))
return false; return false;
} }
if (packaging_params.output_media_info && !on_demand_dash_profile) { if (packaging_params.output_media_info && !on_demand_dash_profile) {
@ -380,7 +373,8 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
if (stream_iter->input != previous_input) { if (stream_iter->input != previous_input) {
// New remux job needed. Create demux and job thread. // New remux job needed. Create demux and job thread.
std::unique_ptr<Demuxer> demuxer(new Demuxer(stream_iter->input)); std::unique_ptr<Demuxer> demuxer(new Demuxer(stream_iter->input));
demuxer->set_dump_stream_info(FLAGS_dump_stream_info); demuxer->set_dump_stream_info(
packaging_params.test_params.dump_stream_info);
if (packaging_params.decryption_params.key_provider != if (packaging_params.decryption_params.key_provider !=
KeyProvider::kNone) { KeyProvider::kNone) {
std::unique_ptr<KeySource> decryption_key_source( std::unique_ptr<KeySource> decryption_key_source(
@ -409,7 +403,8 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
std::shared_ptr<Muxer> muxer( std::shared_ptr<Muxer> muxer(
CreateOutputMuxer(stream_muxer_options, output_format)); CreateOutputMuxer(stream_muxer_options, output_format));
if (FLAGS_use_fake_clock_for_muxer) muxer->set_clock(fake_clock); if (packaging_params.test_params.inject_fake_clock)
muxer->set_clock(fake_clock);
std::unique_ptr<MuxerListener> muxer_listener; std::unique_ptr<MuxerListener> muxer_listener;
DCHECK(!(packaging_params.output_media_info && mpd_notifier)); DCHECK(!(packaging_params.output_media_info && mpd_notifier));
@ -577,7 +572,8 @@ ShakaPackager::~ShakaPackager() {}
Status ShakaPackager::Initialize( Status ShakaPackager::Initialize(
const PackagingParams& packaging_params, const PackagingParams& packaging_params,
const std::vector<StreamDescriptor>& stream_descriptors) { const std::vector<StreamDescriptor>& stream_descriptors) {
// Needed by base::WorkedPool used in ThreadedIoFile.
static base::AtExitManager exit;
static media::LibcryptoThreading libcrypto_threading; static media::LibcryptoThreading libcrypto_threading;
if (internal_) if (internal_)
@ -586,6 +582,11 @@ Status ShakaPackager::Initialize(
if (!media::ValidateParams(packaging_params, stream_descriptors)) if (!media::ValidateParams(packaging_params, stream_descriptors))
return Status(error::INVALID_ARGUMENT, "Invalid packaging params."); return Status(error::INVALID_ARGUMENT, "Invalid packaging params.");
if (!packaging_params.test_params.injected_library_version.empty()) {
SetPackagerVersionForTesting(
packaging_params.test_params.injected_library_version);
}
std::unique_ptr<PackagerInternal> internal(new PackagerInternal); std::unique_ptr<PackagerInternal> internal(new PackagerInternal);
ChunkingOptions chunking_options = ChunkingOptions chunking_options =
@ -680,4 +681,8 @@ void ShakaPackager::Cancel() {
job->demuxer()->Cancel(); job->demuxer()->Cancel();
} }
std::string ShakaPackager::GetLibraryVersion() {
return GetPackagerVersion();
}
} // namespace shaka } // namespace shaka

View File

@ -11,7 +11,7 @@
'targets': [ 'targets': [
{ {
'target_name': 'libpackager', 'target_name': 'libpackager',
'type': 'static_library', 'type': '<(libpackager_type)',
'sources': [ 'sources': [
'packager.cc', 'packager.cc',
'packager.h', 'packager.h',
@ -37,7 +37,15 @@
'media/trick_play/trick_play.gyp:trick_play', 'media/trick_play/trick_play.gyp:trick_play',
'mpd/mpd.gyp:mpd_builder', 'mpd/mpd.gyp:mpd_builder',
'third_party/boringssl/boringssl.gyp:boringssl', 'third_party/boringssl/boringssl.gyp:boringssl',
'third_party/gflags/gflags.gyp:gflags', 'version/version.gyp:version',
],
'conditions': [
['libpackager_type=="shared_library"', {
'defines': [
'SHARED_LIBRARY_BUILD',
'SHAKA_IMPLEMENTATION',
],
}],
], ],
}, },
{ {
@ -69,7 +77,9 @@
'app/widevine_encryption_flags.h', 'app/widevine_encryption_flags.h',
], ],
'dependencies': [ 'dependencies': [
'base/base.gyp:base',
'libpackager', 'libpackager',
'media/file/file.gyp:file',
'third_party/gflags/gflags.gyp:gflags', 'third_party/gflags/gflags.gyp:gflags',
], ],
'conditions': [ 'conditions': [
@ -102,9 +112,10 @@
'packager_test.cc', 'packager_test.cc',
], ],
'dependencies': [ 'dependencies': [
'base/base.gyp:base',
'libpackager', 'libpackager',
'media/test/media_test.gyp:media_test_support',
'testing/gtest.gyp:gtest', 'testing/gtest.gyp:gtest',
'testing/gtest.gyp:gtest_main',
], ],
}, },
{ {

View File

@ -17,6 +17,29 @@
// TODO(kqyang): Refactor status.h and move it under packager/. // TODO(kqyang): Refactor status.h and move it under packager/.
#include "packager/media/base/status.h" #include "packager/media/base/status.h"
#if defined(SHARED_LIBRARY_BUILD)
#if defined(OS_WIN)
#if defined(SHAKA_IMPLEMENTATION)
#define SHAKA_EXPORT __declspec(dllexport)
#else
#define SHAKA_EXPORT __declspec(dllimport)
#endif // defined(SHAKA_IMPLEMENTATION)
#else // defined(OS_WIN)
#if defined(SHAKA_IMPLEMENTATION)
#define SHAKA_EXPORT __attribute__((visibility("default")))
#else
#define SHAKA_EXPORT
#endif
#endif // defined(OS_WIN)
#else // defined(SHARED_LIBRARY_BUILD)
#define SHAKA_EXPORT
#endif // defined(SHARED_LIBRARY_BUILD)
namespace shaka { namespace shaka {
/// MP4 (ISO-BMFF) output related parameters. /// MP4 (ISO-BMFF) output related parameters.
@ -268,7 +291,7 @@ struct EncryptionParams {
/// @param stream_info Encrypted stream info. /// @param stream_info Encrypted stream info.
/// @return the stream label associated with `stream_info`. Can be "AUDIO", /// @return the stream label associated with `stream_info`. Can be "AUDIO",
/// "SD", "HD", "UHD1" or "UHD2". /// "SD", "HD", "UHD1" or "UHD2".
static std::string DefaultStreamLabelFunction( static SHAKA_EXPORT std::string DefaultStreamLabelFunction(
int max_sd_pixels, int max_sd_pixels,
int max_hd_pixels, int max_hd_pixels,
int max_uhd1_pixels, int max_uhd1_pixels,
@ -321,6 +344,18 @@ struct DecryptionParams {
RawKeyDecryptionParams raw_key; RawKeyDecryptionParams raw_key;
}; };
/// Parameters used for testing.
struct TestParams {
/// Whether to dump input stream info.
bool dump_stream_info = false;
/// Inject a fake clock which always returns 0. This allows deterministic
/// output from packaging.
bool inject_fake_clock = false;
/// Inject and replace the library version string if specified, which is used
/// to populate the version string in the manifests / media files.
std::string injected_library_version;
};
/// Packaging parameters. /// Packaging parameters.
struct PackagingParams { struct PackagingParams {
/// Specify temporary directory for intermediate temporary files. /// Specify temporary directory for intermediate temporary files.
@ -343,6 +378,9 @@ struct PackagingParams {
/// Encryption and Decryption Parameters. /// Encryption and Decryption Parameters.
EncryptionParams encryption_params; EncryptionParams encryption_params;
DecryptionParams decryption_params; DecryptionParams decryption_params;
// Parameters for testing. Do not use in production.
TestParams test_params;
}; };
/// Defines a single input/output stream. /// Defines a single input/output stream.
@ -394,7 +432,7 @@ struct StreamDescriptor {
std::string hls_playlist_name; std::string hls_playlist_name;
}; };
class ShakaPackager { class SHAKA_EXPORT ShakaPackager {
public: public:
ShakaPackager(); ShakaPackager();
~ShakaPackager(); ~ShakaPackager();
@ -415,6 +453,9 @@ class ShakaPackager {
/// Cancel packaging. Note that it has to be called from another thread. /// Cancel packaging. Note that it has to be called from another thread.
void Cancel(); void Cancel();
/// @return The version of the library.
static std::string GetLibraryVersion();
private: private:
ShakaPackager(const ShakaPackager&) = delete; ShakaPackager(const ShakaPackager&) = delete;
ShakaPackager& operator=(const ShakaPackager&) = delete; ShakaPackager& operator=(const ShakaPackager&) = delete;

View File

@ -7,8 +7,8 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "packager/base/files/file_util.h" #include "packager/base/files/file_util.h"
#include "packager/media/base/test/status_test_util.h" #include "packager/base/logging.h"
#include "packager/media/test/test_data_util.h" #include "packager/base/path_service.h"
#include "packager/packager.h" #include "packager/packager.h"
namespace shaka { namespace shaka {
@ -26,6 +26,18 @@ const char kKeyIdHex[] = "e5007e6e9dcd5ac095202ed3758382cd";
const char kKeyHex[] = "6fc96fe628a265b13aeddec0bc421f4d"; const char kKeyHex[] = "6fc96fe628a265b13aeddec0bc421f4d";
const double kClearLeadInSeconds = 1.0; const double kClearLeadInSeconds = 1.0;
std::string GetTestDataFilePath(const std::string& name) {
base::FilePath file_path;
CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
file_path = file_path.Append(FILE_PATH_LITERAL("packager"))
.Append(FILE_PATH_LITERAL("media"))
.Append(FILE_PATH_LITERAL("test"))
.Append(FILE_PATH_LITERAL("data"))
.AppendASCII(name);
return file_path.AsUTF8Unsafe();
}
} // namespace } // namespace
class PackagerTest : public ::testing::Test { class PackagerTest : public ::testing::Test {
@ -64,14 +76,12 @@ class PackagerTest : public ::testing::Test {
std::vector<StreamDescriptor> stream_descriptors; std::vector<StreamDescriptor> stream_descriptors;
StreamDescriptor stream_descriptor; StreamDescriptor stream_descriptor;
stream_descriptor.input = stream_descriptor.input = GetTestDataFilePath(kTestFile);
media::GetTestDataFilePath(kTestFile).AsUTF8Unsafe();
stream_descriptor.stream_selector = "video"; stream_descriptor.stream_selector = "video";
stream_descriptor.output = GetFullPath(kOutputVideo); stream_descriptor.output = GetFullPath(kOutputVideo);
stream_descriptors.push_back(stream_descriptor); stream_descriptors.push_back(stream_descriptor);
stream_descriptor.input = stream_descriptor.input = GetTestDataFilePath(kTestFile);
media::GetTestDataFilePath(kTestFile).AsUTF8Unsafe();
stream_descriptor.stream_selector = "audio"; stream_descriptor.stream_selector = "audio";
stream_descriptor.output = GetFullPath(kOutputAudio); stream_descriptor.output = GetFullPath(kOutputAudio);
stream_descriptors.push_back(stream_descriptor); stream_descriptors.push_back(stream_descriptor);
@ -83,11 +93,16 @@ class PackagerTest : public ::testing::Test {
base::FilePath test_directory_; base::FilePath test_directory_;
}; };
TEST_F(PackagerTest, Version) {
EXPECT_FALSE(ShakaPackager::GetLibraryVersion().empty());
}
TEST_F(PackagerTest, Success) { TEST_F(PackagerTest, Success) {
ShakaPackager packager; ShakaPackager packager;
ASSERT_OK( ASSERT_TRUE(
packager.Initialize(SetupPackagingParams(), SetupStreamDescriptors())); packager.Initialize(SetupPackagingParams(), SetupStreamDescriptors())
ASSERT_OK(packager.Run()); .ok());
ASSERT_TRUE(packager.Run().ok());
} }
TEST_F(PackagerTest, MissingStreamDescriptors) { TEST_F(PackagerTest, MissingStreamDescriptors) {
@ -101,15 +116,13 @@ TEST_F(PackagerTest, MixingSegmentTemplateAndSingleSegment) {
std::vector<StreamDescriptor> stream_descriptors; std::vector<StreamDescriptor> stream_descriptors;
StreamDescriptor stream_descriptor; StreamDescriptor stream_descriptor;
stream_descriptor.input = stream_descriptor.input = GetTestDataFilePath(kTestFile);
media::GetTestDataFilePath(kTestFile).AsUTF8Unsafe();
stream_descriptor.stream_selector = "video"; stream_descriptor.stream_selector = "video";
stream_descriptor.output = GetFullPath(kOutputVideo); stream_descriptor.output = GetFullPath(kOutputVideo);
stream_descriptor.segment_template = GetFullPath(kOutputVideoTemplate); stream_descriptor.segment_template = GetFullPath(kOutputVideoTemplate);
stream_descriptors.push_back(stream_descriptor); stream_descriptors.push_back(stream_descriptor);
stream_descriptor.input = stream_descriptor.input = GetTestDataFilePath(kTestFile);
media::GetTestDataFilePath(kTestFile).AsUTF8Unsafe();
stream_descriptor.stream_selector = "audio"; stream_descriptor.stream_selector = "audio";
stream_descriptor.output = GetFullPath(kOutputAudio); stream_descriptor.output = GetFullPath(kOutputAudio);
stream_descriptor.segment_template.clear(); stream_descriptor.segment_template.clear();
@ -125,8 +138,9 @@ TEST_F(PackagerTest, SegmentAlignedAndSubsegmentNotAligned) {
packaging_params.chunking_params.segment_sap_aligned = true; packaging_params.chunking_params.segment_sap_aligned = true;
packaging_params.chunking_params.subsegment_sap_aligned = false; packaging_params.chunking_params.subsegment_sap_aligned = false;
ShakaPackager packager; ShakaPackager packager;
ASSERT_OK(packager.Initialize(packaging_params, SetupStreamDescriptors())); ASSERT_TRUE(
ASSERT_OK(packager.Run()); packager.Initialize(packaging_params, SetupStreamDescriptors()).ok());
ASSERT_TRUE(packager.Run().ok());
} }
TEST_F(PackagerTest, SegmentNotAlignedButSubsegmentAligned) { TEST_F(PackagerTest, SegmentNotAlignedButSubsegmentAligned) {

167
packager/protoc.gypi Normal file
View File

@ -0,0 +1,167 @@
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file is meant to be included into a target to provide a rule
# to invoke protoc in a consistent manner. For Java-targets, see
# protoc_java.gypi.
#
# To use this, create a gyp target with the following form:
# {
# 'target_name': 'my_proto_lib',
# 'type': 'static_library',
# 'sources': [
# 'foo.proto',
# 'bar.proto',
# ],
# 'variables': {
# # Optional, see below: 'proto_in_dir': '.'
# 'proto_out_dir': 'dir/for/my_proto_lib'
# },
# 'includes': ['path/to/this/gypi/file'],
# }
# If necessary, you may add normal .cc files to the sources list or other gyp
# dependencies. The proto headers are guaranteed to be generated before any
# source files, even within this target, are compiled.
#
# The 'proto_in_dir' variable must be the relative path to the
# directory containing the .proto files. If left out, it defaults to '.'.
#
# The 'proto_out_dir' variable specifies the path suffix that output
# files are generated under. Targets that gyp-depend on my_proto_lib
# will be able to include the resulting proto headers with an include
# like:
# #include "dir/for/my_proto_lib/foo.pb.h"
#
# If you need to add an EXPORT macro to a protobuf's c++ header, set the
# 'cc_generator_options' variable with the value: 'dllexport_decl=FOO_EXPORT:'
# e.g. 'dllexport_decl=BASE_EXPORT:'
#
# It is likely you also need to #include a file for the above EXPORT macro to
# work. You can do so with the 'cc_include' variable.
# e.g. 'base/base_export.h'
#
# Implementation notes:
# A proto_out_dir of foo/bar produces
# <(SHARED_INTERMEDIATE_DIR)/protoc_out/foo/bar/{file1,file2}.pb.{cc,h}
# <(SHARED_INTERMEDIATE_DIR)/pyproto/foo/bar/{file1,file2}_pb2.py
{
'variables': {
'protoc_wrapper': '<(DEPTH)/tools/protoc_wrapper/protoc_wrapper.py',
'cc_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out/<(proto_out_dir)',
'py_dir': '<(PRODUCT_DIR)/pyproto/<(proto_out_dir)',
'cc_generator_options%': '',
'generate_python%': 1,
'generate_cc%': 1,
# Name of plugin executable which generates custom cc stubs.
# If passed, generator_plugin_suffix (before .cc and .h) is also required.
'generator_plugin%': '',
'generator_plugin_options%': '',
'cc_include%': '',
'proto_in_dir%': '.',
'conditions': [
['use_system_protobuf==0', {
'protoc': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
}, { # use_system_protobuf==1
'protoc': '<!(which protoc)',
}],
],
},
'rules': [
{
'rule_name': 'genproto',
'extension': 'proto',
'inputs': [
'<(protoc_wrapper)',
'<(protoc)',
],
'action': [
'python',
'<(protoc_wrapper)',
# If no cc_include specified --protobuf option will be ignored.
'--include',
'<(cc_include)',
'--protobuf',
'<(cc_dir)/<(RULE_INPUT_ROOT).pb.h',
# Using the --arg val form (instead of --arg=val) allows gyp's msvs rule
# generation to correct 'val' which is a path.
'--proto-in-dir','<(proto_in_dir)',
# Naively you'd use <(RULE_INPUT_PATH) here, but protoc requires
# --proto_path is a strict prefix of the path given as an argument.
'--proto-in-file','<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)',
'--use-system-protobuf=<(use_system_protobuf)',
'--',
'<(protoc)',
],
'message': 'Generating C++ and Python code from <(RULE_INPUT_PATH)',
'process_outputs_as_sources': 1,
'conditions': [
['generate_python==1', {
'outputs': [
'<(py_dir)/<(RULE_INPUT_ROOT)_pb2.py',
],
'action': [
'--python_out',
'<(py_dir)',
],
}],
['generate_cc==1', {
'outputs': [
'<(cc_dir)/<(RULE_INPUT_ROOT).pb.cc',
'<(cc_dir)/<(RULE_INPUT_ROOT).pb.h',
],
'action': [
'--cpp_out',
'<(cc_generator_options)<(cc_dir)',
],
}],
['generator_plugin!=""', {
'outputs': [
'<(cc_dir)/<(RULE_INPUT_ROOT)<(generator_plugin_suffix).cc',
'<(cc_dir)/<(RULE_INPUT_ROOT)<(generator_plugin_suffix).h',
],
'action': [
'--plugin',
'protoc-gen-plugin=<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)<(generator_plugin)<(EXECUTABLE_SUFFIX)',
'--plugin_out',
'<(generator_plugin_options)<(cc_dir)',
],
}],
],
},
],
'dependencies': [
'<(DEPTH)/third_party/protobuf/protobuf.gyp:protoc#host',
],
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)/protoc_out',
'<(DEPTH)',
],
'direct_dependent_settings': {
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)/protoc_out',
'<(DEPTH)',
]
},
# This target exports a hard dependency because it generates header files.
'hard_dependency': 1,
# If using built-in cc generator the resulting headers reference headers
# within protobuf_lite, hence dependencies require those headers too.
# In case of generator plugin such issues should be resolved by invoker.
'conditions': [
['generate_cc==1', {
'dependencies': [
# Use 'protobuf_full_do_not_use' to allow generating non-LITE (full)
# protobuf. We need full protobuf to serialize and deserialize human
# readable protobuf messages.
'<(DEPTH)/third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
],
'export_dependent_settings': [
'<(DEPTH)/third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use',
],
}],
],
}

View File

@ -6,8 +6,9 @@
#include "packager/version/version.h" #include "packager/version/version.h"
#include "packager/base/lazy_instance.h" #include "packager/base/synchronization/read_write_lock.h"
namespace shaka {
namespace { namespace {
#if defined(PACKAGER_VERSION) #if defined(PACKAGER_VERSION)
@ -29,29 +30,37 @@ class Version {
Version() : version_(kPackagerVersion) {} Version() : version_(kPackagerVersion) {}
~Version() {} ~Version() {}
const std::string& version() { return version_; } const std::string& GetVersion() {
void set_version(const std::string& version) { version_ = version; } base::subtle::AutoReadLock read_lock(lock_);
return version_;
}
void SetVersion(const std::string& version) {
base::subtle::AutoWriteLock write_lock(lock_);
version_ = version;
}
private: private:
Version(const Version&) = delete;
Version& operator=(const Version&) = delete;
base::subtle::ReadWriteLock lock_;
std::string version_; std::string version_;
}; };
} // namespace } // namespace
namespace shaka { static Version g_packager_version;
base::LazyInstance<Version> g_packager_version;
std::string GetPackagerProjectUrl(){ std::string GetPackagerProjectUrl(){
return kPackagerGithubUrl; return kPackagerGithubUrl;
} }
std::string GetPackagerVersion() { std::string GetPackagerVersion() {
return g_packager_version.Get().version(); return g_packager_version.GetVersion();
} }
void SetPackagerVersionForTesting(const std::string& version) { void SetPackagerVersionForTesting(const std::string& version) {
g_packager_version.Get().set_version(version); g_packager_version.SetVersion(version);
} }
} // namespace shaka } // namespace shaka