From faa9a3ea68bf31c5a6e28380457405624e9e08a8 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Tue, 6 Aug 2019 17:03:33 -0700 Subject: [PATCH] [HLS Packed Audio] Truncate timestamp to 33 bits Fixes #629. Change-Id: Iadbbb28de051bf6b8b08561c152a3c1c2014aa80 --- .../packed_audio/packed_audio_segmenter.cc | 5 +++ .../packed_audio_segmenter_unittest.cc | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/packager/media/formats/packed_audio/packed_audio_segmenter.cc b/packager/media/formats/packed_audio/packed_audio_segmenter.cc index 6053dfca97..1057e8273b 100644 --- a/packager/media/formats/packed_audio/packed_audio_segmenter.cc +++ b/packager/media/formats/packed_audio/packed_audio_segmenter.cc @@ -18,6 +18,11 @@ namespace shaka { namespace media { namespace { 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; buffer.AppendInt(timestamp); return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size()); diff --git a/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc b/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc index 65e12ae14d..3566d5c502 100644 --- a/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc +++ b/packager/media/formats/packed_audio/packed_audio_segmenter_unittest.cc @@ -58,11 +58,14 @@ const int64_t kPts1 = 0x12345; const int64_t kDts1 = 0x12000; const int64_t kPts2 = 0x12445; const int64_t kDts2 = 0x12100; +const int64_t kLargePts = 0x123456781; // String form of kPts1 * kExpectedTimescaleScale. const char kScaledPts1[] = {0, 0, 0, 0, 0, 0x12, 0x34, 0x50}; // String form of kPts2 * kExpectedTimescaleScale. 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 kSegment2Data[] = "segment 2 data"; @@ -192,6 +195,35 @@ TEST_F(PackedAudioSegmenterTest, AacAddSample) { 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 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) { ASSERT_OK(segmenter_.Initialize(*CreateAudioStreamInfo(kCodecAC3)));