Remove the usage of JsonWriter in SimpleHlsNotifier

Use protobuf utilities instead.

packager/base/json_writer comes from Chromium base. We are going
to switch to abseil which does not have a JSON library.

This is unfortunately, at the expense of increased output binary size.
packager binary increases by about 300KB due to:
- Protos cannot be compiled with LITE_RUNTIME any more.
- Additional protobuf library needed to convert between JSON and proto.

Change-Id: I45a497376925b42d147ffcaabcfc2fa4dbdeacc1
This commit is contained in:
KongQun Yang 2018-05-04 14:26:39 -07:00
parent bbd5e074ee
commit b209aeeb7a
6 changed files with 119 additions and 41 deletions

View File

@ -10,13 +10,13 @@
#include "packager/base/base64.h" #include "packager/base/base64.h"
#include "packager/base/files/file_path.h" #include "packager/base/files/file_path.h"
#include "packager/base/json/json_writer.h"
#include "packager/base/logging.h" #include "packager/base/logging.h"
#include "packager/base/optional.h" #include "packager/base/optional.h"
#include "packager/base/strings/string_number_conversions.h" #include "packager/base/strings/string_number_conversions.h"
#include "packager/base/strings/stringprintf.h" #include "packager/base/strings/stringprintf.h"
#include "packager/hls/base/media_playlist.h" #include "packager/hls/base/media_playlist.h"
#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/protection_system_specific_info.h"
#include "packager/media/base/proto_json_util.h"
#include "packager/media/base/raw_key_pssh_generator.h" #include "packager/media/base/raw_key_pssh_generator.h"
#include "packager/media/base/raw_key_source.h" #include "packager/media/base/raw_key_source.h"
#include "packager/media/base/widevine_key_source.h" #include "packager/media/base/widevine_key_source.h"
@ -150,31 +150,21 @@ bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_box,
return false; return false;
} }
base::DictionaryValue pssh_dict; media::WidevineHeader widevine_header;
pssh_dict.SetString("provider", pssh_proto.provider()); widevine_header.set_provider(pssh_proto.provider());
if (pssh_proto.has_content_id()) { if (pssh_proto.has_content_id())
std::string content_id_base64; widevine_header.set_content_id(pssh_proto.content_id());
base::Base64Encode(base::StringPiece(pssh_proto.content_id().data(), // Place the current |key_id| to the front and converts all key_id to hex
pssh_proto.content_id().size()), // format.
&content_id_base64); widevine_header.add_key_ids(base::HexEncode(key_id.data(), key_id.size()));
pssh_dict.SetString("content_id", content_id_base64); for (const std::string& key_id_in_pssh : pssh_proto.key_id()) {
const std::string key_id_hex =
base::HexEncode(key_id_in_pssh.data(), key_id_in_pssh.size());
if (widevine_header.key_ids(0) != key_id_hex)
widevine_header.add_key_ids(key_id_hex);
} }
base::ListValue* key_ids = new base::ListValue();
key_ids->AppendString(base::HexEncode(key_id.data(), key_id.size())); *pssh_json = media::MessageToJsonString(widevine_header);
for (const std::string& id : pssh_proto.key_id()) {
if (key_id.size() == id.size() &&
memcmp(key_id.data(), id.data(), id.size()) == 0) {
continue;
}
key_ids->AppendString(base::HexEncode(id.data(), id.size()));
}
pssh_dict.Set("key_ids", key_ids);
if (!base::JSONWriter::Write(pssh_dict, pssh_json)) {
LOG(ERROR) << "Failed to write to JSON.";
return false;
}
return true; return true;
} }

View File

@ -500,10 +500,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
pssh_builder.add_key_id(any_key_id); pssh_builder.add_key_id(any_key_id);
const char kExpectedJson[] = const char kExpectedJson[] =
"{" R"({"key_ids":["11223344112233441122334411223344"],)"
"\"content_id\":\"Y29udGVudGlk\"," R"("provider":"someprovider","content_id":"Y29udGVudGlk"})";
"\"key_ids\":[\"11223344112233441122334411223344\"],"
"\"provider\":\"someprovider\"}";
std::string expected_json_base64; std::string expected_json_base64;
base::Base64Encode(kExpectedJson, &expected_json_base64); base::Base64Encode(kExpectedJson, &expected_json_base64);
@ -547,10 +545,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
widevine_pssh_data_str.end()); widevine_pssh_data_str.end());
const char kExpectedJson[] = const char kExpectedJson[] =
"{" R"({"key_ids":["11223344112233441122334411223344"],)"
"\"content_id\":\"Y29udGVudGlk\"," R"("provider":"someprovider","content_id":"Y29udGVudGlk"})";
"\"key_ids\":[\"11223344112233441122334411223344\"],"
"\"provider\":\"someprovider\"}";
std::string expected_json_base64; std::string expected_json_base64;
base::Base64Encode(kExpectedJson, &expected_json_base64); base::Base64Encode(kExpectedJson, &expected_json_base64);
@ -655,10 +651,10 @@ TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
pssh_builder.add_key_id(second_keyid); pssh_builder.add_key_id(second_keyid);
const char kExpectedJson[] = const char kExpectedJson[] =
"{" R"({)"
"\"key_ids\":[\"22222222222222222222222222222222\"," R"("key_ids":["22222222222222222222222222222222",)"
"\"11111111111111111111111111111111\"]," R"("11111111111111111111111111111111"],)"
"\"provider\":\"someprovider\"}"; R"("provider":"someprovider"})";
std::string expected_json_base64; std::string expected_json_base64;
base::Base64Encode(kExpectedJson, &expected_json_base64); base::Base64Encode(kExpectedJson, &expected_json_base64);
@ -801,10 +797,8 @@ TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) {
widevine_pssh_data_str.end()); widevine_pssh_data_str.end());
const char kExpectedJson[] = const char kExpectedJson[] =
"{" R"({"key_ids":["11223344112233441122334411223344"],)"
"\"content_id\":\"Y29udGVudGlk\"," R"("provider":"someprovider","content_id":"Y29udGVudGlk"})";
"\"key_ids\":[\"11223344112233441122334411223344\"],"
"\"provider\":\"someprovider\"}";
std::string expected_json_base64; std::string expected_json_base64;
base::Base64Encode(kExpectedJson, &expected_json_base64); base::Base64Encode(kExpectedJson, &expected_json_base64);

View File

@ -77,6 +77,8 @@
'producer_consumer_queue.h', 'producer_consumer_queue.h',
'protection_system_specific_info.cc', 'protection_system_specific_info.cc',
'protection_system_specific_info.h', 'protection_system_specific_info.h',
'proto_json_util.cc',
'proto_json_util.h',
'pssh_generator.cc', 'pssh_generator.cc',
'pssh_generator.h', 'pssh_generator.h',
'pssh_generator_util.cc', 'pssh_generator_util.cc',

View File

@ -0,0 +1,42 @@
// Copyright 2018 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "packager/media/base/proto_json_util.h"
#include <google/protobuf/util/json_util.h>
#include "packager/base/logging.h"
namespace shaka {
namespace media {
std::string MessageToJsonString(const google::protobuf::Message& message) {
google::protobuf::util::JsonPrintOptions json_print_options;
json_print_options.preserve_proto_field_names = true;
std::string result;
GOOGLE_CHECK_OK(google::protobuf::util::MessageToJsonString(
message, &result, json_print_options));
return result;
}
bool JsonStringToMessage(const std::string& input,
google::protobuf::Message* message) {
google::protobuf::util::JsonParseOptions json_parse_options;
json_parse_options.ignore_unknown_fields = true;
auto status = google::protobuf::util::JsonStringToMessage(input, message,
json_parse_options);
if (!status.ok()) {
LOG(ERROR) << "Failed to parse from JSON: " << input
<< " error: " << status.error_message();
return false;
}
return true;
}
} // namespace media
} // namespace shaka

View File

@ -0,0 +1,36 @@
// Copyright 2018 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
#define PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
#include <string>
namespace google {
namespace protobuf {
class Message;
} // namespace protobuf
} // namespace google
namespace shaka {
namespace media {
/// Convert protobuf message to JSON.
/// @param message is a protobuf message.
/// @return The protobuf message in JSON format.
std::string MessageToJsonString(const google::protobuf::Message& message);
/// Convert JSON to protobuf message.
/// @param input is the JSON form of a protobuf message.
/// @param message will contain the protobuf message on success.
/// @return true on success, false otherwise.
bool JsonStringToMessage(const std::string& input,
google::protobuf::Message* message);
} // namespace media
} // namespace shaka
#endif // PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_

View File

@ -7,7 +7,6 @@
// This file defines Widevine Pssh Data proto format. // This file defines Widevine Pssh Data proto format.
syntax = "proto2"; syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package shaka.media; package shaka.media;
@ -40,3 +39,18 @@ message WidevinePsshData {
// 'cens' (AES-CTR subsample), 'cbcs' (AES-CBC subsample). // 'cens' (AES-CTR subsample), 'cbcs' (AES-CBC subsample).
optional uint32 protection_scheme = 9; optional uint32 protection_scheme = 9;
} }
// Derived from WidevinePsshData. The JSON format of this proto is used in
// Widevine HLS DRM signaling v1.
// We cannot build JSON from WidevinePsshData as |key_id| is required to be in
// hex format, while |bytes| type is translated to base64 by JSON formatter, so
// we have to use |string| type and do hex conversion in the code.
message WidevineHeader {
repeated string key_ids = 2;
// Content provider name.
optional string provider = 3;
// A content identifier, specified by content provider.
optional bytes content_id = 4;
}