Fix HLS packaging failure with clear lead = 0
- Add MuxerListener::OnEncryptionStart() for notifying that further segments are encrypted. b/29621230 Change-Id: I881b29d55baaf3d04e005a3b95d898071c3f272b
This commit is contained in:
parent
e0c5874d31
commit
db70721e35
|
@ -146,7 +146,6 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
|||
const std::string& group_id,
|
||||
uint32_t* stream_id) {
|
||||
DCHECK(stream_id);
|
||||
*stream_id = sequence_number_.GetNext();
|
||||
|
||||
MediaPlaylist::MediaPlaylistType type;
|
||||
switch (profile()) {
|
||||
|
@ -171,6 +170,7 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
|||
return false;
|
||||
}
|
||||
|
||||
*stream_id = sequence_number_.GetNext();
|
||||
base::AutoLock auto_lock(lock_);
|
||||
master_playlist_->AddMediaPlaylist(media_playlist.get());
|
||||
media_playlist_map_.insert(
|
||||
|
|
|
@ -36,6 +36,12 @@ void HlsNotifyMuxerListener::OnEncryptionInfoReady(
|
|||
const std::vector<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_infos) {
|
||||
if (!media_started_) {
|
||||
next_key_id_ = key_id;
|
||||
next_iv_ = iv;
|
||||
next_key_system_infos_ = key_system_infos;
|
||||
return;
|
||||
}
|
||||
for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
|
||||
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
||||
stream_id_, key_id, info.system_id(), iv, info.pssh_data());
|
||||
|
@ -43,6 +49,28 @@ void HlsNotifyMuxerListener::OnEncryptionInfoReady(
|
|||
}
|
||||
}
|
||||
|
||||
void HlsNotifyMuxerListener::OnEncryptionStart() {
|
||||
if (!media_started_) {
|
||||
DLOG(WARNING) << "Media not started, cannot notify encryption start.";
|
||||
return;
|
||||
}
|
||||
if (next_key_id_.empty()) {
|
||||
DCHECK(next_iv_.empty());
|
||||
DCHECK(next_key_system_infos_.empty());
|
||||
return;
|
||||
}
|
||||
|
||||
for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
|
||||
const bool result = hls_notifier_->NotifyEncryptionUpdate(
|
||||
stream_id_, next_key_id_, info.system_id(), next_iv_,
|
||||
info.pssh_data());
|
||||
LOG_IF(WARNING, !result) << "Failed to add encryption info";
|
||||
}
|
||||
next_key_id_.clear();
|
||||
next_iv_.clear();
|
||||
next_key_system_infos_.clear();
|
||||
}
|
||||
|
||||
void HlsNotifyMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
uint32_t time_scale,
|
||||
|
@ -56,7 +84,12 @@ void HlsNotifyMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
|
|||
const bool result = hls_notifier_->NotifyNewStream(
|
||||
media_info, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
|
||||
&stream_id_);
|
||||
LOG_IF(WARNING, !result) << "Failed to notify new stream.";
|
||||
if (!result) {
|
||||
LOG(WARNING) << "Failed to notify new stream.";
|
||||
return;
|
||||
}
|
||||
|
||||
media_started_ = true;
|
||||
}
|
||||
|
||||
void HlsNotifyMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {}
|
||||
|
|
|
@ -45,6 +45,7 @@ class HlsNotifyMuxerListener : public MuxerListener {
|
|||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>&
|
||||
key_system_info) override;
|
||||
void OnEncryptionStart() override;
|
||||
void OnMediaStart(const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
uint32_t time_scale,
|
||||
|
@ -71,6 +72,12 @@ class HlsNotifyMuxerListener : public MuxerListener {
|
|||
hls::HlsNotifier* const hls_notifier_;
|
||||
uint32_t stream_id_ = 0;
|
||||
|
||||
bool media_started_ = false;
|
||||
// Cached encryption info before OnMediaStart() is called.
|
||||
std::vector<uint8_t> next_key_id_;
|
||||
std::vector<uint8_t> next_iv_;
|
||||
std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HlsNotifyMuxerListener);
|
||||
};
|
||||
|
||||
|
|
|
@ -83,7 +83,126 @@ class HlsNotifyMuxerListenerTest : public ::testing::Test {
|
|||
HlsNotifyMuxerListener listener_;
|
||||
};
|
||||
|
||||
// Verify that NotifyEncryptionUpdate() is not called before OnMediaStart() is
|
||||
// called.
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReadyBeforeMediaStart) {
|
||||
ProtectionSystemSpecificInfo info;
|
||||
std::vector<uint8_t> system_id(kAnySystemId,
|
||||
kAnySystemId + arraysize(kAnySystemId));
|
||||
info.set_system_id(system_id.data(), system_id.size());
|
||||
std::vector<uint8_t> pssh_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
info.set_pssh_data(pssh_data);
|
||||
|
||||
std::vector<uint8_t> key_id(16, 0x05);
|
||||
std::vector<ProtectionSystemSpecificInfo> key_system_infos;
|
||||
key_system_infos.push_back(info);
|
||||
|
||||
std::vector<uint8_t> iv(16, 0x54);
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, _, _, _, _)).Times(0);
|
||||
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
||||
iv, key_system_infos);
|
||||
}
|
||||
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnMediaStart) {
|
||||
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||
scoped_refptr<StreamInfo> video_stream_info =
|
||||
CreateVideoStreamInfo(video_params);
|
||||
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyNewStream(_, StrEq(kDefaultPlaylistName),
|
||||
StrEq("DEFAULTNAME"), StrEq("DEFAULTGROUPID"), _))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
MuxerOptions muxer_options;
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
MuxerListener::kContainerMpeg2ts);
|
||||
}
|
||||
|
||||
// OnEncryptionStart() should NotifyEncryptionUpdate() after
|
||||
// OnEncryptionInfoReady() and OnMediaStart().
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionStart) {
|
||||
ProtectionSystemSpecificInfo info;
|
||||
std::vector<uint8_t> system_id(kAnySystemId,
|
||||
kAnySystemId + arraysize(kAnySystemId));
|
||||
info.set_system_id(system_id.data(), system_id.size());
|
||||
std::vector<uint8_t> pssh_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
info.set_pssh_data(pssh_data);
|
||||
|
||||
std::vector<uint8_t> key_id(16, 0x05);
|
||||
std::vector<ProtectionSystemSpecificInfo> key_system_infos;
|
||||
key_system_infos.push_back(info);
|
||||
|
||||
std::vector<uint8_t> iv(16, 0x54);
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, _, _, _, _)).Times(0);
|
||||
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
||||
iv, key_system_infos);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||
|
||||
ON_CALL(mock_notifier_, NotifyNewStream(_, _, _, _, _))
|
||||
.WillByDefault(Return(true));
|
||||
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||
scoped_refptr<StreamInfo> video_stream_info =
|
||||
CreateVideoStreamInfo(video_params);
|
||||
MuxerOptions muxer_options;
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, _, _, _, _)).Times(0);
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
MuxerListener::kContainerMpeg2ts);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyEncryptionUpdate(_, key_id, system_id, iv, pssh_data))
|
||||
.WillOnce(Return(true));
|
||||
listener_.OnEncryptionStart();
|
||||
}
|
||||
|
||||
// NotifyEncryptionUpdate() should not be called if NotifyNewStream() fails in
|
||||
// OnMediaStart().
|
||||
TEST_F(HlsNotifyMuxerListenerTest, NoEncryptionUpdateIfNotifyNewStreamFails) {
|
||||
ProtectionSystemSpecificInfo info;
|
||||
std::vector<uint8_t> system_id(kAnySystemId,
|
||||
kAnySystemId + arraysize(kAnySystemId));
|
||||
info.set_system_id(system_id.data(), system_id.size());
|
||||
std::vector<uint8_t> pssh_data(kAnyData, kAnyData + arraysize(kAnyData));
|
||||
info.set_pssh_data(pssh_data);
|
||||
|
||||
std::vector<uint8_t> key_id(16, 0x05);
|
||||
std::vector<ProtectionSystemSpecificInfo> key_system_infos;
|
||||
key_system_infos.push_back(info);
|
||||
|
||||
std::vector<uint8_t> iv(16, 0x54);
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, _, _, _, _)).Times(0);
|
||||
listener_.OnEncryptionInfoReady(kInitialEncryptionInfo, FOURCC_cbcs, key_id,
|
||||
iv, key_system_infos);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_notifier_);
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyNewStream(_, _, _, _, _))
|
||||
.WillOnce(Return(false));
|
||||
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||
scoped_refptr<StreamInfo> video_stream_info =
|
||||
CreateVideoStreamInfo(video_params);
|
||||
MuxerOptions muxer_options;
|
||||
|
||||
EXPECT_CALL(mock_notifier_, NotifyEncryptionUpdate(_, _, _, _, _)).Times(0);
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
MuxerListener::kContainerMpeg2ts);
|
||||
}
|
||||
|
||||
// Verify that after OnMediaStart(), OnEncryptionInfoReady() calls
|
||||
// NotifyEncryptionUpdate().
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReady) {
|
||||
ON_CALL(mock_notifier_, NotifyNewStream(_, _, _, _, _))
|
||||
.WillByDefault(Return(true));
|
||||
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||
scoped_refptr<StreamInfo> video_stream_info =
|
||||
CreateVideoStreamInfo(video_params);
|
||||
MuxerOptions muxer_options;
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
MuxerListener::kContainerMpeg2ts);
|
||||
|
||||
ProtectionSystemSpecificInfo info;
|
||||
std::vector<uint8_t> system_id(kAnySystemId,
|
||||
kAnySystemId + arraysize(kAnySystemId));
|
||||
|
@ -104,21 +223,6 @@ TEST_F(HlsNotifyMuxerListenerTest, OnEncryptionInfoReady) {
|
|||
iv, key_system_infos);
|
||||
}
|
||||
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnMediaStart) {
|
||||
VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams();
|
||||
scoped_refptr<StreamInfo> video_stream_info =
|
||||
CreateVideoStreamInfo(video_params);
|
||||
|
||||
EXPECT_CALL(mock_notifier_,
|
||||
NotifyNewStream(_, StrEq(kDefaultPlaylistName),
|
||||
StrEq("DEFAULTNAME"), StrEq("DEFAULTGROUPID"), _))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
MuxerOptions muxer_options;
|
||||
listener_.OnMediaStart(muxer_options, *video_stream_info, 90000,
|
||||
MuxerListener::kContainerMpeg2ts);
|
||||
}
|
||||
|
||||
// Make sure it doesn't crash.
|
||||
TEST_F(HlsNotifyMuxerListenerTest, OnSampleDurationReady) {
|
||||
listener_.OnSampleDurationReady(2340);
|
||||
|
|
|
@ -30,6 +30,8 @@ class MockMuxerListener : public MuxerListener {
|
|||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info));
|
||||
|
||||
MOCK_METHOD0(OnEncryptionStart, void());
|
||||
|
||||
MOCK_METHOD4(OnMediaStart,
|
||||
void(const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
|
|
|
@ -54,6 +54,8 @@ void MpdNotifyMuxerListener::OnEncryptionInfoReady(
|
|||
}
|
||||
}
|
||||
|
||||
void MpdNotifyMuxerListener::OnEncryptionStart() {}
|
||||
|
||||
void MpdNotifyMuxerListener::OnMediaStart(
|
||||
const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
|
|
|
@ -39,6 +39,7 @@ class MpdNotifyMuxerListener : public MuxerListener {
|
|||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>&
|
||||
key_system_info) override;
|
||||
void OnEncryptionStart() override;
|
||||
void OnMediaStart(const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
uint32_t time_scale,
|
||||
|
|
|
@ -64,6 +64,12 @@ class MuxerListener {
|
|||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>& key_system_info) = 0;
|
||||
|
||||
/// Called when the muxer starts encrypting the segments.
|
||||
/// Further segments notified via OnNewSegment() are encrypted.
|
||||
/// This may be called more than once e.g. per segment, but the semantics does
|
||||
/// not change.
|
||||
virtual void OnEncryptionStart() = 0;
|
||||
|
||||
/// Called when muxing starts.
|
||||
/// For MPEG DASH Live profile, the initialization segment information is
|
||||
/// available from StreamInfo.
|
||||
|
|
|
@ -62,6 +62,8 @@ void VodMediaInfoDumpMuxerListener::OnMediaStart(
|
|||
}
|
||||
}
|
||||
|
||||
void VodMediaInfoDumpMuxerListener::OnEncryptionStart() {}
|
||||
|
||||
void VodMediaInfoDumpMuxerListener::OnSampleDurationReady(
|
||||
uint32_t sample_duration) {
|
||||
// Assume one VideoInfo.
|
||||
|
|
|
@ -38,6 +38,7 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
|||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<ProtectionSystemSpecificInfo>&
|
||||
key_system_info) override;
|
||||
void OnEncryptionStart() override;
|
||||
void OnMediaStart(const MuxerOptions& muxer_options,
|
||||
const StreamInfo& stream_info,
|
||||
uint32_t time_scale,
|
||||
|
|
|
@ -57,8 +57,18 @@ Status TsSegmenter::Initialize(const StreamInfo& stream_info,
|
|||
}
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
||||
encryption_key_ = encryption_key.Pass();
|
||||
clear_lead_in_seconds_ = clear_lead_in_seconds;
|
||||
|
||||
if (listener_) {
|
||||
// For now this only happens once, so send true.
|
||||
const bool kIsInitialEncryptionInfo = true;
|
||||
listener_->OnEncryptionInfoReady(
|
||||
kIsInitialEncryptionInfo, FOURCC_cbcs, encryption_key_->key_id,
|
||||
encryption_key_->iv, encryption_key_->key_system_info);
|
||||
}
|
||||
|
||||
status = NotifyEncrypted();
|
||||
if (!status.ok())
|
||||
return status;
|
||||
|
@ -174,13 +184,8 @@ Status TsSegmenter::Flush() {
|
|||
|
||||
Status TsSegmenter::NotifyEncrypted() {
|
||||
if (encryption_key_ && total_duration_in_seconds_ >= clear_lead_in_seconds_) {
|
||||
if (listener_) {
|
||||
// For now this only happens once, so send true.
|
||||
const bool kIsInitialEncryptionInfo = true;
|
||||
listener_->OnEncryptionInfoReady(
|
||||
kIsInitialEncryptionInfo, FOURCC_cbcs, encryption_key_->key_id,
|
||||
encryption_key_->iv, encryption_key_->key_system_info);
|
||||
}
|
||||
if (listener_)
|
||||
listener_->OnEncryptionStart();
|
||||
|
||||
if (!pes_packet_generator_->SetEncryptionKey(encryption_key_.Pass()))
|
||||
return Status(error::INTERNAL_ERROR, "Failed to set encryption key.");
|
||||
|
|
|
@ -481,6 +481,44 @@ TEST_F(TsSegmenterTest, WithEncryptionNoClearLead) {
|
|||
kClearLeadSeconds));
|
||||
}
|
||||
|
||||
// Verify that the muxer listener pointer is not used without checking that it's
|
||||
// not null.
|
||||
TEST_F(TsSegmenterTest, WithEncryptionNoClearLeadNoMuxerListener) {
|
||||
scoped_refptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264VideoCodec, kCodecString, kLanguage,
|
||||
kWidth, kHeight, kPixelWidth, kPixelHeight, kTrickPlayRate,
|
||||
kNaluLengthSize, kExtraData, arraysize(kExtraData), kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_duration = 10.0;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
|
||||
TsSegmenter segmenter(options, nullptr);
|
||||
|
||||
EXPECT_CALL(*mock_ts_writer_, Initialize(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_ts_writer_, SignalEncypted());
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, Initialize(_))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, SetEncryptionKeyMock(_))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
segmenter.InjectTsWriterForTesting(mock_ts_writer_.Pass());
|
||||
segmenter.InjectPesPacketGeneratorForTesting(
|
||||
mock_pes_packet_generator_.Pass());
|
||||
|
||||
MockKeySource mock_key_source;
|
||||
EXPECT_CALL(mock_key_source, GetKey(KeySource::TRACK_TYPE_HD, _))
|
||||
.WillOnce(Return(Status::OK));
|
||||
|
||||
const uint32_t k480pPixels = 640 * 480;
|
||||
// Set this to 0 so that Finalize will call
|
||||
// PesPacketGenerator::SetEncryptionKey().
|
||||
// Even tho no samples have been added.
|
||||
const double kClearLeadSeconds = 0;
|
||||
EXPECT_OK(segmenter.Initialize(*stream_info, &mock_key_source, k480pPixels,
|
||||
kClearLeadSeconds));
|
||||
}
|
||||
|
||||
// Verify that encryption notification is sent to objects after clear lead.
|
||||
TEST_F(TsSegmenterTest, WithEncryptionWithClearLead) {
|
||||
scoped_refptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
|
@ -568,13 +606,14 @@ TEST_F(TsSegmenterTest, WithEncryptionWithClearLead) {
|
|||
EXPECT_CALL(mock_key_source, GetKey(KeySource::TRACK_TYPE_HD, _))
|
||||
.WillOnce(Return(Status::OK));
|
||||
|
||||
EXPECT_CALL(mock_listener, OnEncryptionInfoReady(_, _, _, _, _));
|
||||
EXPECT_OK(segmenter.Initialize(*stream_info, &mock_key_source, 0,
|
||||
kClearLeadSeconds));
|
||||
EXPECT_OK(segmenter.AddSample(sample1));
|
||||
|
||||
// These should be called AFTER the first AddSample(), before the second
|
||||
// segment.
|
||||
EXPECT_CALL(mock_listener, OnEncryptionInfoReady(_, _, _, _, _));
|
||||
EXPECT_CALL(mock_listener, OnEncryptionStart());
|
||||
EXPECT_CALL(*mock_pes_packet_generator_raw, SetEncryptionKeyMock(_))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_ts_writer_raw, SignalEncypted());
|
||||
|
|
|
@ -66,7 +66,8 @@ EncryptingFragmenter::EncryptingFragmenter(
|
|||
int64_t clear_time,
|
||||
FourCC protection_scheme,
|
||||
uint8_t crypt_byte_block,
|
||||
uint8_t skip_byte_block)
|
||||
uint8_t skip_byte_block,
|
||||
MuxerListener* listener)
|
||||
: Fragmenter(info, traf),
|
||||
info_(info),
|
||||
encryption_key_(encryption_key.Pass()),
|
||||
|
@ -75,7 +76,8 @@ EncryptingFragmenter::EncryptingFragmenter(
|
|||
clear_time_(clear_time),
|
||||
protection_scheme_(protection_scheme),
|
||||
crypt_byte_block_(crypt_byte_block),
|
||||
skip_byte_block_(skip_byte_block) {
|
||||
skip_byte_block_(skip_byte_block),
|
||||
listener_(listener) {
|
||||
DCHECK(encryption_key_);
|
||||
switch (video_codec_) {
|
||||
case kCodecVP8:
|
||||
|
@ -143,6 +145,9 @@ Status EncryptingFragmenter::InitializeFragment(int64_t first_sample_dts) {
|
|||
traf()->header.flags |=
|
||||
TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
|
||||
traf()->header.sample_description_index = kClearSampleDescriptionIndex;
|
||||
} else {
|
||||
if (listener_)
|
||||
listener_->OnEncryptionStart();
|
||||
}
|
||||
return PrepareFragmentForEncryption(enable_encryption);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/codecs/video_slice_header_parser.h"
|
||||
#include "packager/media/codecs/vpx_parser.h"
|
||||
#include "packager/media/event/muxer_listener.h"
|
||||
#include "packager/media/formats/mp4/fragmenter.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -43,7 +44,8 @@ class EncryptingFragmenter : public Fragmenter {
|
|||
int64_t clear_time,
|
||||
FourCC protection_scheme,
|
||||
uint8_t crypt_byte_block,
|
||||
uint8_t skip_byte_block);
|
||||
uint8_t skip_byte_block,
|
||||
MuxerListener* listener);
|
||||
|
||||
~EncryptingFragmenter() override;
|
||||
|
||||
|
@ -95,6 +97,7 @@ class EncryptingFragmenter : public Fragmenter {
|
|||
const FourCC protection_scheme_;
|
||||
const uint8_t crypt_byte_block_;
|
||||
const uint8_t skip_byte_block_;
|
||||
MuxerListener* listener_;
|
||||
|
||||
scoped_ptr<VPxParser> vpx_parser_;
|
||||
scoped_ptr<VideoSliceHeaderParser> header_parser_;
|
||||
|
|
|
@ -34,7 +34,8 @@ KeyRotationFragmenter::KeyRotationFragmenter(MovieFragment* moof,
|
|||
clear_time,
|
||||
protection_scheme,
|
||||
crypt_byte_block,
|
||||
skip_byte_block),
|
||||
skip_byte_block,
|
||||
muxer_listener),
|
||||
moof_(moof),
|
||||
encryption_key_source_(encryption_key_source),
|
||||
track_type_(track_type),
|
||||
|
|
|
@ -259,7 +259,8 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
fragmenters_[i] = new EncryptingFragmenter(
|
||||
streams[i]->info(), &moof_->tracks[i], encryption_key.Pass(),
|
||||
clear_lead_in_seconds * streams[i]->info()->time_scale(),
|
||||
protection_scheme, pattern.crypt_byte_block, pattern.skip_byte_block);
|
||||
protection_scheme, pattern.crypt_byte_block, pattern.skip_byte_block,
|
||||
muxer_listener_);
|
||||
}
|
||||
|
||||
// Choose the first stream if there is no VIDEO.
|
||||
|
|
|
@ -166,6 +166,8 @@ Status Segmenter::AddSample(scoped_refptr<MediaSample> sample) {
|
|||
LOG(ERROR) << "Error encrypting frame.";
|
||||
return status;
|
||||
}
|
||||
if (encrypt_frame && muxer_listener_)
|
||||
muxer_listener_->OnEncryptionStart();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue