[HLS Packed Audio] Truncate timestamp to 33 bits

Fixes #629.

Change-Id: Iadbbb28de051bf6b8b08561c152a3c1c2014aa80
This commit is contained in:
KongQun Yang 2019-08-06 17:03:33 -07:00
parent edd776eea2
commit faa9a3ea68
2 changed files with 37 additions and 0 deletions

View File

@ -18,6 +18,11 @@ namespace shaka {
namespace media { namespace media {
namespace { namespace {
std::string TimestampToString(uint64_t timestamp) { std::string TimestampToString(uint64_t timestamp) {
// https://tools.ietf.org/html/rfc8216 The ID3 payload MUST be a 33-bit MPEG-2
// Program Elementary Stream timestamp expressed as a big-endian eight-octet
// number, with the upper 31 bits set to zero.
timestamp &= 0x1FFFFFFFFull;
BufferWriter buffer; BufferWriter buffer;
buffer.AppendInt(timestamp); buffer.AppendInt(timestamp);
return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size()); return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size());

View File

@ -58,11 +58,14 @@ const int64_t kPts1 = 0x12345;
const int64_t kDts1 = 0x12000; const int64_t kDts1 = 0x12000;
const int64_t kPts2 = 0x12445; const int64_t kPts2 = 0x12445;
const int64_t kDts2 = 0x12100; const int64_t kDts2 = 0x12100;
const int64_t kLargePts = 0x123456781;
// String form of kPts1 * kExpectedTimescaleScale. // String form of kPts1 * kExpectedTimescaleScale.
const char kScaledPts1[] = {0, 0, 0, 0, 0, 0x12, 0x34, 0x50}; const char kScaledPts1[] = {0, 0, 0, 0, 0, 0x12, 0x34, 0x50};
// String form of kPts2 * kExpectedTimescaleScale. // String form of kPts2 * kExpectedTimescaleScale.
const char kScaledPts2[] = {0, 0, 0, 0, 0, 0x12, 0x44, 0x50}; const char kScaledPts2[] = {0, 0, 0, 0, 0, 0x12, 0x44, 0x50};
// String form of kLargePts * kExpectedTimescaleScale truncated to 33 bits.
const char kTruncatedScaledLargePts[] = {0, 0, 0, 0, 0x34, 0x56, 0x78, 0x10};
const char kSegment1Data[] = "segment 1 data"; const char kSegment1Data[] = "segment 1 data";
const char kSegment2Data[] = "segment 2 data"; const char kSegment2Data[] = "segment 2 data";
@ -192,6 +195,35 @@ TEST_F(PackedAudioSegmenterTest, AacAddSample) {
EXPECT_EQ(std::string(kSegment1Data) + kAdtsSample1Data, GetSegmentData()); EXPECT_EQ(std::string(kSegment1Data) + kAdtsSample1Data, GetSegmentData());
} }
TEST_F(PackedAudioSegmenterTest, TruncateLargeTimestamp) {
EXPECT_CALL(*mock_adts_converter_, Parse(ElementsAreArray(kCodecConfig)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_adts_converter_,
ConvertToADTS(Pointee(Eq(StringToVector(kSample1Data)))))
.WillOnce(DoAll(SetArgPointee<0>(StringToVector(kAdtsSample1Data)),
Return(true)));
EXPECT_CALL(segmenter_, CreateAdtsConverter())
.WillOnce(Return(ByMove(std::move(mock_adts_converter_))));
ASSERT_OK(segmenter_.Initialize(*CreateAudioStreamInfo(kCodecAAC)));
std::unique_ptr<MockId3Tag> mock_id3_tag(new MockId3Tag);
EXPECT_CALL(*mock_id3_tag,
AddPrivateFrame(kTimestampOwnerIdentifier,
std::string(std::begin(kTruncatedScaledLargePts),
std::end(kTruncatedScaledLargePts))));
EXPECT_CALL(*mock_id3_tag, WriteToBuffer(_))
.WillOnce(Invoke([](BufferWriter* buffer) {
buffer->AppendString(kSegment1Data);
return true;
}));
EXPECT_CALL(segmenter_, CreateId3Tag())
.WillOnce(Return(ByMove(std::move(mock_id3_tag))));
ASSERT_OK(
segmenter_.AddSample(*CreateSample(kLargePts, kLargePts, kSample1Data)));
}
TEST_F(PackedAudioSegmenterTest, Ac3AddSample) { TEST_F(PackedAudioSegmenterTest, Ac3AddSample) {
ASSERT_OK(segmenter_.Initialize(*CreateAudioStreamInfo(kCodecAC3))); ASSERT_OK(segmenter_.Initialize(*CreateAudioStreamInfo(kCodecAC3)));