Scale sample duration in TsSegmenter
- Sample duration wasn't scaled in TsSegmenter to calculate the current segment's length. So segmenting length did not always respect segment_duration. Change-Id: I1ef4747dbd12bde7852ffcbceb971f2775aa18b3
This commit is contained in:
parent
bbf9c6849b
commit
102f3f7062
|
@ -16,7 +16,7 @@ namespace media {
|
|||
namespace mp2t {
|
||||
|
||||
namespace {
|
||||
const int kTsTimescale = 90000;
|
||||
const double kTsTimescale = 90000;
|
||||
} // namespace
|
||||
|
||||
TsSegmenter::TsSegmenter(const MuxerOptions& options)
|
||||
|
@ -35,6 +35,7 @@ Status TsSegmenter::Initialize(const StreamInfo& stream_info) {
|
|||
"Failed to initialize PesPacketGenerator.");
|
||||
}
|
||||
|
||||
timescale_scale_ = kTsTimescale / stream_info.time_scale();
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
|
@ -62,7 +63,9 @@ Status TsSegmenter::AddSample(scoped_refptr<MediaSample> sample) {
|
|||
"Failed to add sample to PesPacketGenerator.");
|
||||
}
|
||||
|
||||
current_segment_total_sample_duration_ += sample->duration() / kTsTimescale;
|
||||
const double scaled_sample_duration = sample->duration() * timescale_scale_;
|
||||
current_segment_total_sample_duration_ +=
|
||||
scaled_sample_duration / kTsTimescale;
|
||||
|
||||
return WritePesPacketsToFile();
|
||||
}
|
||||
|
|
|
@ -66,7 +66,14 @@ class TsSegmenter {
|
|||
|
||||
const MuxerOptions& muxer_options_;
|
||||
|
||||
// in seconds.
|
||||
// Scale used to scale the input stream to TS's timesccale (which is 90000).
|
||||
// Used for calculating the duration in seconds fo the current segment.
|
||||
double timescale_scale_ = 1.0;
|
||||
|
||||
// This is the sum of the durations of the samples that were added to
|
||||
// PesPacketGenerator for the current segment (in seconds). Note that this is
|
||||
// not necessarily the same as the length of the PesPackets that have been
|
||||
// written to the current segment in WritePesPacketsToFile().
|
||||
double current_segment_total_sample_duration_ = 0.0;
|
||||
|
||||
// Used for segment template.
|
||||
|
|
|
@ -72,9 +72,6 @@ class MockTsWriter : public TsWriter {
|
|||
// No need to keep the pes packet around for the current tests.
|
||||
return AddPesPacketMock(pes_packet.get());
|
||||
}
|
||||
|
||||
MOCK_METHOD0(NotifyReinjectPsi, bool());
|
||||
MOCK_CONST_METHOD0(TimeScale, uint32_t());
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -120,9 +117,6 @@ TEST_F(TsSegmenterTest, AddSample) {
|
|||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options);
|
||||
|
||||
ON_CALL(*mock_ts_writer_, TimeScale())
|
||||
.WillByDefault(Return(kTimeScale));
|
||||
|
||||
EXPECT_CALL(*mock_ts_writer_, Initialize(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, Initialize(_))
|
||||
.WillOnce(Return(true));
|
||||
|
@ -169,17 +163,18 @@ TEST_F(TsSegmenterTest, AddSample) {
|
|||
// This will add 2 samples and verify that the first segment is closed when the
|
||||
// second sample is added.
|
||||
TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
||||
// Use something significantly smaller than 90000 to check that the scaling is
|
||||
// done correctly in the segmenter.
|
||||
const uint32_t kInputTimescale = 1001;
|
||||
scoped_refptr<VideoStreamInfo> stream_info(new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kH264VideoCodec, kCodecString, kLanguage,
|
||||
kWidth, kHeight, kPixelWidth, kPixelHeight, kTrickPlayRate,
|
||||
kTrackId, kInputTimescale, 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);
|
||||
|
||||
ON_CALL(*mock_ts_writer_, TimeScale()).WillByDefault(Return(kTimeScale));
|
||||
|
||||
EXPECT_CALL(*mock_ts_writer_, Initialize(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, Initialize(_))
|
||||
.WillOnce(Return(true));
|
||||
|
@ -194,10 +189,10 @@ TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
|||
|
||||
// 11 seconds > 10 seconds (segment duration).
|
||||
// Expect the segment to be finalized.
|
||||
sample1->set_duration(kTimeScale * 11);
|
||||
sample1->set_duration(kInputTimescale * 11);
|
||||
|
||||
// Doesn't really matter how long this is.
|
||||
sample2->set_duration(kTimeScale * 7);
|
||||
sample2->set_duration(kInputTimescale * 7);
|
||||
|
||||
Sequence writer_sequence;
|
||||
EXPECT_CALL(*mock_ts_writer_, NewSegment(StrEq("file1.ts")))
|
||||
|
@ -328,8 +323,6 @@ TEST_F(TsSegmenterTest, SegmentOnlyBeforeKeyFrame) {
|
|||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options);
|
||||
|
||||
ON_CALL(*mock_ts_writer_, TimeScale()).WillByDefault(Return(kTimeScale));
|
||||
|
||||
EXPECT_CALL(*mock_ts_writer_, Initialize(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_pes_packet_generator_, Initialize(_))
|
||||
.WillOnce(Return(true));
|
||||
|
|
Loading…
Reference in New Issue