Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PSSH boxes generator for live packager #10

Merged
merged 18 commits into from
Jan 16, 2024
Merged
18 changes: 16 additions & 2 deletions include/packager/live_packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#define PACKAGER_LIVE_PACKAGER_H_

#include <packager/packager.h>
#include <memory>
#include <string>

namespace shaka {

Expand Down Expand Up @@ -86,8 +84,24 @@ struct LiveConfig {
std::vector<uint8_t> key;
std::vector<uint8_t> key_id;
EncryptionScheme protection_scheme;

bool include_pssh;
};

struct PSSHData {
std::vector<uint8_t> cenc_box;
std::vector<uint8_t> mspr_box;
std::vector<uint8_t> wv_box;
};

struct KeyData {
std::vector<uint8_t> curr_key;
std::vector<uint8_t> curr_key_id;
std::vector<std::vector<uint8_t>> all_key_ids;
};

Status GeneratePSSHData(PSSHData* data, const std::vector<KeyData>& all_keys, const KeyData& current_key, uint32_t encryption_scheme);

class LivePackager {
public:
LivePackager(const LiveConfig& config);
Expand Down
63 changes: 63 additions & 0 deletions packager/live_packager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@
#include <absl/log/log.h>
#include <packager/chunking_params.h>
#include <packager/file.h>

#include <packager/macros/status.h>
#include <packager/live_packager.h>
#include <packager/media/base/aes_encryptor.h>
#include <packager/packager.h>

#include "media/base/common_pssh_generator.h"
#include "media/base/playready_pssh_generator.h"
#include "media/base/protection_system_ids.h"
#include "media/base/pssh_generator.h"
#include "media/base/widevine_pssh_generator.h"

namespace shaka {

namespace {
Expand Down Expand Up @@ -296,6 +304,61 @@ Status LivePackager::Package(const Segment& in, FullSegmentBuffer& out) {
return packager.Run();
}

void AddProtectionSystem(
const media::ProtectionSystemSpecificInfo& pssh_info,
PSSHData* data) {
if (const std::vector<uint8_t> common_system_id(
jedekar marked this conversation as resolved.
Show resolved Hide resolved
media::kCommonSystemId,
media::kCommonSystemId + std::size(media::kCommonSystemId));
pssh_info.system_id == common_system_id) {
data->cenc_box = pssh_info.psshs;
return;
}

if (const std::vector<uint8_t> widevine_system_id(
media::kWidevineSystemId,
media::kWidevineSystemId + std::size(media::kWidevineSystemId));
pssh_info.system_id == widevine_system_id) {
data->wv_box = pssh_info.psshs;
return;
}

if (const std::vector<uint8_t> playready_system_id(
media::kPlayReadySystemId,
media::kPlayReadySystemId + std::size(media::kPlayReadySystemId));
pssh_info.system_id == playready_system_id) {
data->wv_box = pssh_info.psshs;
}
}

Status GeneratePSSHData(
PSSHData* data, const KeyData& encryption_key, uint32_t protection_scheme) {
const std::string no_extra_headers_playready = "";

std::vector<std::unique_ptr<media::PsshGenerator>> pssh_generators;
pssh_generators.emplace_back(new media::CommonPsshGenerator());
pssh_generators.emplace_back(new media::PlayReadyPsshGenerator(
no_extra_headers_playready, static_cast<media::FourCC>(protection_scheme)));
pssh_generators.emplace_back(new media::WidevinePsshGenerator(static_cast<media::FourCC>(protection_scheme)));

for (const auto& pssh_generator : pssh_generators) {
const bool support_multiple_keys = pssh_generator->SupportMultipleKeys();
if (support_multiple_keys) {
media::ProtectionSystemSpecificInfo info;
RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIds(
encryption_key.all_key_ids, &info));
AddProtectionSystem(info, data);
} else {
media::ProtectionSystemSpecificInfo info;
RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIdAndKey(
encryption_key.curr_key_id, encryption_key.curr_key, &info));
AddProtectionSystem(info, data);
}
}

return Status::OK;
}

SegmentManager::SegmentManager() = default;

int64_t SegmentManager::OnSegmentWrite(const std::string& name,
Expand Down
Loading