Rename trick play rate to trick play factor.
- Add a "tpf" abbreviation in stream descriptor for trick_play_factor. Change-Id: Ia09313bb9778456b53bdb0a8cc46d2ba8caa2ac2
This commit is contained in:
parent
5fc6e540f3
commit
da8877d8a2
|
@ -358,11 +358,11 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
||||||
// Create a new trick_play_handler. Note that the stream_decriptors
|
// Create a new trick_play_handler. Note that the stream_decriptors
|
||||||
// are sorted so that for the same input and stream_selector, the main
|
// are sorted so that for the same input and stream_selector, the main
|
||||||
// stream is always the last one following the trick play streams.
|
// stream is always the last one following the trick play streams.
|
||||||
if (stream_iter->trick_play_rate > 0) {
|
if (stream_iter->trick_play_factor > 0) {
|
||||||
if (!trick_play_handler) {
|
if (!trick_play_handler) {
|
||||||
trick_play_handler.reset(new TrickPlayHandler());
|
trick_play_handler.reset(new TrickPlayHandler());
|
||||||
}
|
}
|
||||||
trick_play_handler->SetHandlerForTrickPlay(stream_iter->trick_play_rate,
|
trick_play_handler->SetHandlerForTrickPlay(stream_iter->trick_play_factor,
|
||||||
std::move(muxer));
|
std::move(muxer));
|
||||||
if (trick_play_handler->IsConnected())
|
if (trick_play_handler->IsConnected())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -30,7 +30,7 @@ enum FieldType {
|
||||||
kHlsNameField,
|
kHlsNameField,
|
||||||
kHlsGroupIdField,
|
kHlsGroupIdField,
|
||||||
kHlsPlaylistNameField,
|
kHlsPlaylistNameField,
|
||||||
kTrickPlayRateField,
|
kTrickPlayFactorField,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldNameToTypeMapping {
|
struct FieldNameToTypeMapping {
|
||||||
|
@ -58,7 +58,8 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
|
||||||
{"hls_name", kHlsNameField},
|
{"hls_name", kHlsNameField},
|
||||||
{"hls_group_id", kHlsGroupIdField},
|
{"hls_group_id", kHlsGroupIdField},
|
||||||
{"playlist_name", kHlsPlaylistNameField},
|
{"playlist_name", kHlsPlaylistNameField},
|
||||||
{"trick_play_rate", kTrickPlayRateField},
|
{"trick_play_factor", kTrickPlayFactorField},
|
||||||
|
{"tpf", kTrickPlayFactorField},
|
||||||
};
|
};
|
||||||
|
|
||||||
FieldType GetFieldType(const std::string& field_name) {
|
FieldType GetFieldType(const std::string& field_name) {
|
||||||
|
@ -143,18 +144,18 @@ bool InsertStreamDescriptor(const std::string& descriptor_string,
|
||||||
descriptor.hls_playlist_name = iter->second;
|
descriptor.hls_playlist_name = iter->second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kTrickPlayRateField: {
|
case kTrickPlayFactorField: {
|
||||||
unsigned rate;
|
unsigned factor;
|
||||||
if (!base::StringToUint(iter->second, &rate)) {
|
if (!base::StringToUint(iter->second, &factor)) {
|
||||||
LOG(ERROR) << "Non-numeric trick play rate " << iter->second
|
LOG(ERROR) << "Non-numeric trick play factor " << iter->second
|
||||||
<< " specified.";
|
<< " specified.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (rate == 0) {
|
if (factor == 0) {
|
||||||
LOG(ERROR) << "Stream trick_play_rate should be > 0.";
|
LOG(ERROR) << "Stream trick_play_factor should be > 0.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
descriptor.trick_play_rate = rate;
|
descriptor.trick_play_factor = factor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct StreamDescriptor {
|
||||||
std::string hls_name;
|
std::string hls_name;
|
||||||
std::string hls_group_id;
|
std::string hls_group_id;
|
||||||
std::string hls_playlist_name;
|
std::string hls_playlist_name;
|
||||||
uint32_t trick_play_rate = 0;
|
uint32_t trick_play_factor = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamDescriptorCompareFn {
|
class StreamDescriptorCompareFn {
|
||||||
|
@ -41,8 +41,8 @@ class StreamDescriptorCompareFn {
|
||||||
bool operator()(const StreamDescriptor& a, const StreamDescriptor& b) {
|
bool operator()(const StreamDescriptor& a, const StreamDescriptor& b) {
|
||||||
if (a.input == b.input) {
|
if (a.input == b.input) {
|
||||||
if (a.stream_selector == b.stream_selector)
|
if (a.stream_selector == b.stream_selector)
|
||||||
// Stream with high trick_play_rate is at the beginning.
|
// Stream with high trick_play_factor is at the beginning.
|
||||||
return a.trick_play_rate > b.trick_play_rate;
|
return a.trick_play_factor > b.trick_play_factor;
|
||||||
else
|
else
|
||||||
return a.stream_selector < b.stream_selector;
|
return a.stream_selector < b.stream_selector;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
' width: 640\n'
|
' width: 640\n'
|
||||||
' height: 360\n'
|
' height: 360\n'
|
||||||
' pixel_aspect_ratio: 1:1\n'
|
' pixel_aspect_ratio: 1:1\n'
|
||||||
' trick_play_rate: 0\n'
|
' trick_play_factor: 0\n'
|
||||||
' nalu_length_size: 4\n\n'
|
' nalu_length_size: 4\n\n'
|
||||||
'Stream [1] type: Audio\n'
|
'Stream [1] type: Audio\n'
|
||||||
' codec_string: mp4a.40.2\n'
|
' codec_string: mp4a.40.2\n'
|
||||||
|
@ -103,7 +103,7 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
|
|
||||||
def testPackageAudioVideoWithTrickPlay(self):
|
def testPackageAudioVideoWithTrickPlay(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1']),
|
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1']),
|
||||||
self._GetFlags())
|
self._GetFlags())
|
||||||
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
||||||
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
||||||
|
@ -112,8 +112,8 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
|
|
||||||
def testPackageAudioVideoWithTwoTrickPlay(self):
|
def testPackageAudioVideoWithTwoTrickPlay(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1',
|
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1',
|
||||||
'video,trick_play_rate=2']),
|
'video,trick_play_factor=2']),
|
||||||
self._GetFlags())
|
self._GetFlags())
|
||||||
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
||||||
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
||||||
|
@ -124,15 +124,15 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
|
|
||||||
def testPackageAudioVideoWithTwoTrickPlayDecreasingRate(self):
|
def testPackageAudioVideoWithTwoTrickPlayDecreasingRate(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=2',
|
self._GetStreams(['audio', 'video', 'video,trick_play_factor=2',
|
||||||
'video,trick_play_rate=1']),
|
'video,trick_play_factor=1']),
|
||||||
self._GetFlags())
|
self._GetFlags())
|
||||||
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
||||||
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
||||||
self._DiffGold(self.output[2], 'bear-640x360-v-trick-2-golden.mp4')
|
self._DiffGold(self.output[2], 'bear-640x360-v-trick-2-golden.mp4')
|
||||||
self._DiffGold(self.output[3], 'bear-640x360-v-trick-1-golden.mp4')
|
self._DiffGold(self.output[3], 'bear-640x360-v-trick-1-golden.mp4')
|
||||||
# Since the stream descriptors are sorted in packager app, a different
|
# Since the stream descriptors are sorted in packager app, a different
|
||||||
# order of trick play rates gets the same mpd.
|
# order of trick play factors gets the same mpd.
|
||||||
self._DiffGold(self.mpd_output,
|
self._DiffGold(self.mpd_output,
|
||||||
'bear-640x360-av-trick-1-trick-2-golden.mpd')
|
'bear-640x360-av-trick-1-trick-2-golden.mpd')
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
|
|
||||||
def testPackageWithEncryptionAndTrickPlay(self):
|
def testPackageWithEncryptionAndTrickPlay(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1']),
|
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1']),
|
||||||
self._GetFlags(encryption=True))
|
self._GetFlags(encryption=True))
|
||||||
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
||||||
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
||||||
|
@ -256,8 +256,8 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
# play stream.
|
# play stream.
|
||||||
def testPackageWithEncryptionAndTwoTrickPlays(self):
|
def testPackageWithEncryptionAndTwoTrickPlays(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1',
|
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1',
|
||||||
'video,trick_play_rate=2']),
|
'video,trick_play_factor=2']),
|
||||||
self._GetFlags(encryption=True))
|
self._GetFlags(encryption=True))
|
||||||
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
||||||
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</ContentProtection>
|
</ContentProtection>
|
||||||
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
||||||
<Representation id="1" bandwidth="157348" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
|
<Representation id="1" bandwidth="157348" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_1.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="1091-1158" timescale="30000">
|
<SegmentBase indexRange="1091-1158" timescale="30000">
|
||||||
<Initialization range="0-1090"/>
|
<Initialization range="0-1090"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<AdaptationSet id="1" contentType="video" width="640" height="360" frameRate="30000/30030" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="1" contentType="video" width="640" height="360" frameRate="30000/30030" subsegmentAlignment="true" par="16:9">
|
||||||
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
||||||
<Representation id="1" bandwidth="156160" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
|
<Representation id="1" bandwidth="156160" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_1.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="823-890" timescale="30000">
|
<SegmentBase indexRange="823-890" timescale="30000">
|
||||||
<Initialization range="0-822"/>
|
<Initialization range="0-822"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
</ContentProtection>
|
</ContentProtection>
|
||||||
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
||||||
<Representation id="1" bandwidth="104852" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/60060" maxPlayoutRate="60" codingDependency="false">
|
<Representation id="1" bandwidth="104852" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/60060" maxPlayoutRate="60" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_2.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_2.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="1091-1146" timescale="30000">
|
<SegmentBase indexRange="1091-1146" timescale="30000">
|
||||||
<Initialization range="0-1090"/>
|
<Initialization range="0-1090"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
</Representation>
|
</Representation>
|
||||||
<Representation id="2" bandwidth="157348" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false">
|
<Representation id="2" bandwidth="157348" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_1.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="1091-1158" timescale="30000">
|
<SegmentBase indexRange="1091-1158" timescale="30000">
|
||||||
<Initialization range="0-1090"/>
|
<Initialization range="0-1090"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
<AdaptationSet id="1" contentType="video" width="640" height="360" maxFrameRate="30000/30030" par="16:9">
|
<AdaptationSet id="1" contentType="video" width="640" height="360" maxFrameRate="30000/30030" par="16:9">
|
||||||
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
|
||||||
<Representation id="1" bandwidth="103866" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/60060" maxPlayoutRate="60" codingDependency="false">
|
<Representation id="1" bandwidth="103866" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/60060" maxPlayoutRate="60" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_2.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_2.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="823-878" timescale="30000">
|
<SegmentBase indexRange="823-878" timescale="30000">
|
||||||
<Initialization range="0-822"/>
|
<Initialization range="0-822"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
</Representation>
|
</Representation>
|
||||||
<Representation id="2" bandwidth="156160" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false">
|
<Representation id="2" bandwidth="156160" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false">
|
||||||
<BaseURL>output_video_trick_play_rate_1.mp4</BaseURL>
|
<BaseURL>output_video_trick_play_factor_1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="823-890" timescale="30000">
|
<SegmentBase indexRange="823-890" timescale="30000">
|
||||||
<Initialization range="0-822"/>
|
<Initialization range="0-822"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
|
|
|
@ -27,7 +27,7 @@ const uint16_t kWidth = 10u;
|
||||||
const uint16_t kHeight = 20u;
|
const uint16_t kHeight = 20u;
|
||||||
const uint32_t kPixelWidth = 2u;
|
const uint32_t kPixelWidth = 2u;
|
||||||
const uint32_t kPixelHeight = 3u;
|
const uint32_t kPixelHeight = 3u;
|
||||||
const int16_t kTrickPlayRate = 0;
|
const int16_t kTrickPlayFactor = 0;
|
||||||
const uint8_t kNaluLengthSize = 1u;
|
const uint8_t kNaluLengthSize = 1u;
|
||||||
const bool kEncrypted = true;
|
const bool kEncrypted = true;
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ std::shared_ptr<StreamInfo> MediaHandlerTestBase::GetMockStreamInfo(
|
||||||
return std::shared_ptr<StreamInfo>(new VideoStreamInfo(
|
return std::shared_ptr<StreamInfo>(new VideoStreamInfo(
|
||||||
kTrackId, time_scale, kDuration, codec, H26xStreamFormat::kUnSpecified,
|
kTrackId, time_scale, kDuration, codec, H26xStreamFormat::kUnSpecified,
|
||||||
kCodecString, kCodecConfig, sizeof(kCodecConfig), kWidth, kHeight,
|
kCodecString, kCodecConfig, sizeof(kCodecConfig), kWidth, kHeight,
|
||||||
kPixelWidth, kPixelHeight, kTrickPlayRate, kNaluLengthSize, kLanguage,
|
kPixelWidth, kPixelHeight, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||||
!kEncrypted));
|
!kEncrypted));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -48,7 +48,7 @@ VideoStreamInfo::VideoStreamInfo(int track_id,
|
||||||
uint16_t height,
|
uint16_t height,
|
||||||
uint32_t pixel_width,
|
uint32_t pixel_width,
|
||||||
uint32_t pixel_height,
|
uint32_t pixel_height,
|
||||||
uint32_t trick_play_rate,
|
uint32_t trick_play_factor,
|
||||||
uint8_t nalu_length_size,
|
uint8_t nalu_length_size,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
bool is_encrypted)
|
bool is_encrypted)
|
||||||
|
@ -67,7 +67,7 @@ VideoStreamInfo::VideoStreamInfo(int track_id,
|
||||||
height_(height),
|
height_(height),
|
||||||
pixel_width_(pixel_width),
|
pixel_width_(pixel_width),
|
||||||
pixel_height_(pixel_height),
|
pixel_height_(pixel_height),
|
||||||
trick_play_rate_(trick_play_rate),
|
trick_play_factor_(trick_play_factor),
|
||||||
nalu_length_size_(nalu_length_size) {}
|
nalu_length_size_(nalu_length_size) {}
|
||||||
|
|
||||||
VideoStreamInfo::~VideoStreamInfo() {}
|
VideoStreamInfo::~VideoStreamInfo() {}
|
||||||
|
@ -82,9 +82,9 @@ bool VideoStreamInfo::IsValidConfig() const {
|
||||||
std::string VideoStreamInfo::ToString() const {
|
std::string VideoStreamInfo::ToString() const {
|
||||||
return base::StringPrintf(
|
return base::StringPrintf(
|
||||||
"%s codec: %s\n width: %d\n height: %d\n pixel_aspect_ratio: %d:%d\n "
|
"%s codec: %s\n width: %d\n height: %d\n pixel_aspect_ratio: %d:%d\n "
|
||||||
"trick_play_rate: %d\n nalu_length_size: %d\n",
|
"trick_play_factor: %d\n nalu_length_size: %d\n",
|
||||||
StreamInfo::ToString().c_str(), VideoCodecToString(codec()).c_str(),
|
StreamInfo::ToString().c_str(), VideoCodecToString(codec()).c_str(),
|
||||||
width_, height_, pixel_width_, pixel_height_, trick_play_rate_,
|
width_, height_, pixel_width_, pixel_height_, trick_play_factor_,
|
||||||
nalu_length_size_);
|
nalu_length_size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
uint16_t height,
|
uint16_t height,
|
||||||
uint32_t pixel_width,
|
uint32_t pixel_width,
|
||||||
uint32_t pixel_height,
|
uint32_t pixel_height,
|
||||||
uint32_t trick_play_rate,
|
uint32_t trick_play_factor,
|
||||||
uint8_t nalu_length_size,
|
uint8_t nalu_length_size,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
bool is_encrypted);
|
bool is_encrypted);
|
||||||
|
@ -62,7 +62,7 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
/// @return 0 if unknown.
|
/// @return 0 if unknown.
|
||||||
uint32_t pixel_height() const { return pixel_height_; }
|
uint32_t pixel_height() const { return pixel_height_; }
|
||||||
uint8_t nalu_length_size() const { return nalu_length_size_; }
|
uint8_t nalu_length_size() const { return nalu_length_size_; }
|
||||||
uint32_t trick_play_rate() const { return trick_play_rate_; }
|
uint32_t trick_play_factor() const { return trick_play_factor_; }
|
||||||
uint32_t playback_rate() const { return playback_rate_; }
|
uint32_t playback_rate() const { return playback_rate_; }
|
||||||
const std::vector<uint8_t>& eme_init_data() const { return eme_init_data_; }
|
const std::vector<uint8_t>& eme_init_data() const { return eme_init_data_; }
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
void set_height(uint32_t height) { height_ = height; }
|
void set_height(uint32_t height) { height_ = height; }
|
||||||
void set_pixel_width(uint32_t pixel_width) { pixel_width_ = pixel_width; }
|
void set_pixel_width(uint32_t pixel_width) { pixel_width_ = pixel_width; }
|
||||||
void set_pixel_height(uint32_t pixel_height) { pixel_height_ = pixel_height; }
|
void set_pixel_height(uint32_t pixel_height) { pixel_height_ = pixel_height; }
|
||||||
void set_trick_play_rate(uint32_t trick_play_rate) {
|
void set_trick_play_factor(uint32_t trick_play_factor) {
|
||||||
trick_play_rate_ = trick_play_rate;
|
trick_play_factor_ = trick_play_factor;
|
||||||
}
|
}
|
||||||
void set_playback_rate(uint32_t playback_rate) {
|
void set_playback_rate(uint32_t playback_rate) {
|
||||||
playback_rate_ = playback_rate;
|
playback_rate_ = playback_rate;
|
||||||
|
@ -90,7 +90,7 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
// 0 means unknown.
|
// 0 means unknown.
|
||||||
uint32_t pixel_width_;
|
uint32_t pixel_width_;
|
||||||
uint32_t pixel_height_;
|
uint32_t pixel_height_;
|
||||||
uint32_t trick_play_rate_ = 0; // Non-zero for trick-play streams.
|
uint32_t trick_play_factor_ = 0; // Non-zero for trick-play streams.
|
||||||
|
|
||||||
// Playback rate is the attribute for trick play stream, which signals the
|
// Playback rate is the attribute for trick play stream, which signals the
|
||||||
// playout capabilities
|
// playout capabilities
|
||||||
|
@ -99,8 +99,8 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
// frame rate. If the time scale and frame duration are not modified after
|
// frame rate. If the time scale and frame duration are not modified after
|
||||||
// trick play handler processing, the playback_rate equals to the number of
|
// trick play handler processing, the playback_rate equals to the number of
|
||||||
// frames between consecutive key frames selected for trick play stream. For
|
// frames between consecutive key frames selected for trick play stream. For
|
||||||
// example, if the video stream has GOP size of 10 and the trick play rate is
|
// example, if the video stream has GOP size of 10 and the trick play factor
|
||||||
// 3, the key frames are in this trick play stream are [frame_0, frame_30,
|
// is 3, the key frames are in this trick play stream are [frame_0, frame_30,
|
||||||
// frame_60, ...]. Then the playback_rate is 30.
|
// frame_60, ...]. Then the playback_rate is 30.
|
||||||
uint32_t playback_rate_;
|
uint32_t playback_rate_;
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,8 @@ void AddVideoInfo(const VideoStreamInfo* video_stream_info,
|
||||||
video_info->set_decoder_config(&codec_config[0], codec_config.size());
|
video_info->set_decoder_config(&codec_config[0], codec_config.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (video_stream_info->trick_play_rate() > 0) {
|
if (video_stream_info->trick_play_factor() > 0) {
|
||||||
video_info->set_trick_play_rate(video_stream_info->trick_play_rate());
|
video_info->set_trick_play_factor(video_stream_info->trick_play_factor());
|
||||||
CHECK_GT(video_stream_info->playback_rate(), 0u)
|
CHECK_GT(video_stream_info->playback_rate(), 0u)
|
||||||
<< "Max playout rate should be > 0 for trick play streams.";
|
<< "Max playout rate should be > 0 for trick play streams.";
|
||||||
video_info->set_playback_rate(video_stream_info->playback_rate());
|
video_info->set_playback_rate(video_stream_info->playback_rate());
|
||||||
|
|
|
@ -21,7 +21,7 @@ std::shared_ptr<StreamInfo> CreateVideoStreamInfo(
|
||||||
H26xStreamFormat::kUnSpecified, param.codec_string,
|
H26xStreamFormat::kUnSpecified, param.codec_string,
|
||||||
param.codec_config.data(), param.codec_config.size(), param.width,
|
param.codec_config.data(), param.codec_config.size(), param.width,
|
||||||
param.height, param.pixel_width, param.pixel_height,
|
param.height, param.pixel_width, param.pixel_height,
|
||||||
0, // trick_play_rate
|
0, // trick_play_factor
|
||||||
param.nalu_length_size, param.language, param.is_encrypted);
|
param.nalu_length_size, param.language, param.is_encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ const uint32_t kWidth = 1280;
|
||||||
const uint32_t kHeight = 720;
|
const uint32_t kHeight = 720;
|
||||||
const uint32_t kPixelWidth = 1;
|
const uint32_t kPixelWidth = 1;
|
||||||
const uint32_t kPixelHeight = 1;
|
const uint32_t kPixelHeight = 1;
|
||||||
const uint16_t kTrickPlayRate = 1;
|
const uint16_t kTrickPlayFactor = 1;
|
||||||
const uint8_t kNaluLengthSize = 1;
|
const uint8_t kNaluLengthSize = 1;
|
||||||
const bool kIsEncrypted = false;
|
const bool kIsEncrypted = false;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(Codec codec) {
|
||||||
kTrackId, kTimeScale, kDuration, codec,
|
kTrackId, kTimeScale, kDuration, codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
return stream_info;
|
return stream_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ TEST_F(PesPacketGeneratorTest, TimeStampScaling) {
|
||||||
kTrackId, kTestTimescale, kDuration, kH264Codec,
|
kTrackId, kTestTimescale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(generator_.Initialize(*stream_info));
|
EXPECT_TRUE(generator_.Initialize(*stream_info));
|
||||||
|
|
||||||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||||
|
|
|
@ -41,7 +41,7 @@ const uint32_t kWidth = 1280;
|
||||||
const uint32_t kHeight = 720;
|
const uint32_t kHeight = 720;
|
||||||
const uint32_t kPixelWidth = 1;
|
const uint32_t kPixelWidth = 1;
|
||||||
const uint32_t kPixelHeight = 1;
|
const uint32_t kPixelHeight = 1;
|
||||||
const uint16_t kTrickPlayRate = 1;
|
const uint16_t kTrickPlayFactor = 1;
|
||||||
const uint8_t kNaluLengthSize = 1;
|
const uint8_t kNaluLengthSize = 1;
|
||||||
const bool kIsEncrypted = false;
|
const bool kIsEncrypted = false;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ TEST_F(TsSegmenterTest, Initialize) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
TsSegmenter segmenter(options, nullptr);
|
TsSegmenter segmenter(options, nullptr);
|
||||||
|
@ -121,7 +121,7 @@ TEST_F(TsSegmenterTest, AddSample) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
TsSegmenter segmenter(options, nullptr);
|
TsSegmenter segmenter(options, nullptr);
|
||||||
|
@ -173,7 +173,7 @@ TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
||||||
kTrackId, kInputTimescale, kDuration, kH264Codec,
|
kTrackId, kInputTimescale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ TEST_F(TsSegmenterTest, InitializeThenFinalize) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
TsSegmenter segmenter(options, nullptr);
|
TsSegmenter segmenter(options, nullptr);
|
||||||
|
@ -297,7 +297,7 @@ TEST_F(TsSegmenterTest, FinalizeSegment) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
TsSegmenter segmenter(options, nullptr);
|
TsSegmenter segmenter(options, nullptr);
|
||||||
|
@ -325,7 +325,7 @@ TEST_F(TsSegmenterTest, EncryptedSample) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
MuxerOptions options;
|
MuxerOptions options;
|
||||||
|
|
||||||
options.segment_template = "file$Number$.ts";
|
options.segment_template = "file$Number$.ts";
|
||||||
|
|
|
@ -39,7 +39,7 @@ const uint32_t kWidth = 1280;
|
||||||
const uint32_t kHeight = 720;
|
const uint32_t kHeight = 720;
|
||||||
const uint32_t kPixelWidth = 1;
|
const uint32_t kPixelWidth = 1;
|
||||||
const uint32_t kPixelHeight = 1;
|
const uint32_t kPixelHeight = 1;
|
||||||
const uint16_t kTrickPlayRate = 1;
|
const uint16_t kTrickPlayFactor = 1;
|
||||||
const uint8_t kNaluLengthSize = 1;
|
const uint8_t kNaluLengthSize = 1;
|
||||||
const bool kIsEncrypted = false;
|
const bool kIsEncrypted = false;
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ TEST_F(TsWriterTest, InitializeVideoH264) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ TEST_F(TsWriterTest, InitializeVideoNonH264) {
|
||||||
kTrackId, kTimeScale, kDuration, Codec::kCodecVP9,
|
kTrackId, kTimeScale, kDuration, Codec::kCodecVP9,
|
||||||
H26xStreamFormat::kUnSpecified, kCodecString, kExtraData,
|
H26xStreamFormat::kUnSpecified, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_FALSE(ts_writer_.Initialize(*stream_info));
|
EXPECT_FALSE(ts_writer_.Initialize(*stream_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ TEST_F(TsWriterTest, ClearH264Psi) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
|
|
||||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||||
|
@ -287,7 +287,7 @@ TEST_F(TsWriterTest, ClearLeadH264Pmt) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
|
|
||||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||||
|
@ -317,7 +317,7 @@ TEST_F(TsWriterTest, EncryptedSegmentsH264Pmt) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
|
|
||||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||||
|
@ -406,7 +406,7 @@ TEST_F(TsWriterTest, AddPesPacket) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ TEST_F(TsWriterTest, BigPesPacket) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ TEST_F(TsWriterTest, PesPtsZeroNoDts) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ TEST_F(TsWriterTest, TsPacketPayload183Bytes) {
|
||||||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||||
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
EXPECT_TRUE(ts_writer_.NewSegment(test_file_name_));
|
||||||
|
|
||||||
|
|
|
@ -590,7 +590,7 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
||||||
entry.codec_configuration.data.data(),
|
entry.codec_configuration.data.data(),
|
||||||
entry.codec_configuration.data.size(), coded_width, coded_height,
|
entry.codec_configuration.data.size(), coded_width, coded_height,
|
||||||
pixel_width, pixel_height,
|
pixel_width, pixel_height,
|
||||||
0, // trick_play_rate
|
0, // trick_play_factor
|
||||||
nalu_length_size, track->media.header.language.code, is_encrypted));
|
nalu_length_size, track->media.header.language.code, is_encrypted));
|
||||||
|
|
||||||
// Set pssh raw data if it has.
|
// Set pssh raw data if it has.
|
||||||
|
|
|
@ -31,7 +31,7 @@ const uint16_t kWidth = 100;
|
||||||
const uint16_t kHeight = 100;
|
const uint16_t kHeight = 100;
|
||||||
const uint16_t kPixelWidth = 100;
|
const uint16_t kPixelWidth = 100;
|
||||||
const uint16_t kPixelHeight = 100;
|
const uint16_t kPixelHeight = 100;
|
||||||
const int16_t kTrickPlayRate = 1;
|
const int16_t kTrickPlayFactor = 1;
|
||||||
const uint8_t kNaluLengthSize = 0;
|
const uint8_t kNaluLengthSize = 0;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -82,10 +82,10 @@ MuxerOptions SegmentTestBase::CreateMuxerOptions() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoStreamInfo* SegmentTestBase::CreateVideoStreamInfo() const {
|
VideoStreamInfo* SegmentTestBase::CreateVideoStreamInfo() const {
|
||||||
return new VideoStreamInfo(kTrackId, kTimeScale, kDuration, kCodec,
|
return new VideoStreamInfo(
|
||||||
H26xStreamFormat::kUnSpecified, kCodecString, NULL,
|
kTrackId, kTimeScale, kDuration, kCodec, H26xStreamFormat::kUnSpecified,
|
||||||
0, kWidth, kHeight, kPixelWidth, kPixelHeight,
|
kCodecString, NULL, 0, kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||||
kTrickPlayRate, kNaluLengthSize, kLanguage, false);
|
kTrickPlayFactor, kNaluLengthSize, kLanguage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SegmentTestBase::OutputFileName() const {
|
std::string SegmentTestBase::OutputFileName() const {
|
||||||
|
|
|
@ -91,7 +91,7 @@ const uint16_t kWidth = 320u;
|
||||||
const uint16_t kHeight = 180u;
|
const uint16_t kHeight = 180u;
|
||||||
const uint32_t kPixelWidth = 1u;
|
const uint32_t kPixelWidth = 1u;
|
||||||
const uint32_t kPixelHeight = 1u;
|
const uint32_t kPixelHeight = 1u;
|
||||||
const int16_t kTrickPlayRate = 0u;
|
const int16_t kTrickPlayFactor = 0u;
|
||||||
const uint8_t kNaluLengthSize = 0u;
|
const uint8_t kNaluLengthSize = 0u;
|
||||||
|
|
||||||
// Test duration defaults must differ from parser estimation defaults to know
|
// Test duration defaults must differ from parser estimation defaults to know
|
||||||
|
@ -350,7 +350,7 @@ class WebMClusterParserTest : public testing::Test {
|
||||||
kHeight,
|
kHeight,
|
||||||
kPixelWidth,
|
kPixelWidth,
|
||||||
kPixelHeight,
|
kPixelHeight,
|
||||||
kTrickPlayRate,
|
kTrickPlayFactor,
|
||||||
kNaluLengthSize,
|
kNaluLengthSize,
|
||||||
kLanguage,
|
kLanguage,
|
||||||
!kEncrypted)),
|
!kEncrypted)),
|
||||||
|
|
|
@ -574,7 +574,7 @@ bool WvmMediaParser::ParseIndexEntry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t track_duration = 0;
|
uint64_t track_duration = 0;
|
||||||
uint32_t trick_play_rate = 0;
|
uint32_t trick_play_factor = 0;
|
||||||
uint32_t sampling_frequency = kDefaultSamplingFrequency;
|
uint32_t sampling_frequency = kDefaultSamplingFrequency;
|
||||||
uint32_t time_scale = kMpeg2ClockRate;
|
uint32_t time_scale = kMpeg2ClockRate;
|
||||||
uint16_t video_width = 0;
|
uint16_t video_width = 0;
|
||||||
|
@ -680,8 +680,8 @@ bool WvmMediaParser::ParseIndexEntry() {
|
||||||
case TrackDuration:
|
case TrackDuration:
|
||||||
track_duration = value;
|
track_duration = value;
|
||||||
break;
|
break;
|
||||||
case TrackTrickPlayRate:
|
case TrackTrickPlayFactor:
|
||||||
trick_play_rate = value;
|
trick_play_factor = value;
|
||||||
break;
|
break;
|
||||||
case VideoStreamId:
|
case VideoStreamId:
|
||||||
video_pes_stream_id = value;
|
video_pes_stream_id = value;
|
||||||
|
@ -743,7 +743,7 @@ bool WvmMediaParser::ParseIndexEntry() {
|
||||||
stream_id_count_, time_scale, track_duration, kCodecH264,
|
stream_id_count_, time_scale, track_duration, kCodecH264,
|
||||||
byte_to_unit_stream_converter_.stream_format(), std::string(),
|
byte_to_unit_stream_converter_.stream_format(), std::string(),
|
||||||
video_codec_config.data(), video_codec_config.size(), video_width,
|
video_codec_config.data(), video_codec_config.size(), video_width,
|
||||||
video_height, pixel_width, pixel_height, trick_play_rate,
|
video_height, pixel_width, pixel_height, trick_play_factor,
|
||||||
nalu_length_size, std::string(),
|
nalu_length_size, std::string(),
|
||||||
decryption_key_source_ ? false : true));
|
decryption_key_source_ ? false : true));
|
||||||
program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
|
program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
|
||||||
|
|
|
@ -69,7 +69,7 @@ class WvmMediaParser : public MediaParser {
|
||||||
TrackSize = 2,
|
TrackSize = 2,
|
||||||
TrackDuration = 3,
|
TrackDuration = 3,
|
||||||
TrackBitRate = 4,
|
TrackBitRate = 4,
|
||||||
TrackTrickPlayRate = 5,
|
TrackTrickPlayFactor = 5,
|
||||||
TrackAdaptationInterval = 6,
|
TrackAdaptationInterval = 6,
|
||||||
TrackFlags = 7,
|
TrackFlags = 7,
|
||||||
VideoType = 8,
|
VideoType = 8,
|
||||||
|
|
|
@ -26,11 +26,11 @@ void TrickPlayHandler::SetHandlerForMainStream(
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrickPlayHandler::SetHandlerForTrickPlay(
|
void TrickPlayHandler::SetHandlerForTrickPlay(
|
||||||
uint32_t trick_play_rate,
|
uint32_t trick_play_factor,
|
||||||
std::shared_ptr<MediaHandler> handler) {
|
std::shared_ptr<MediaHandler> handler) {
|
||||||
trick_play_rates_.push_back(trick_play_rate);
|
trick_play_factors_.push_back(trick_play_factor);
|
||||||
// Trick play streams start from index 1.
|
// Trick play streams start from index 1.
|
||||||
SetHandler(trick_play_rates_.size(), std::move(handler));
|
SetHandler(trick_play_factors_.size(), std::move(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
Status TrickPlayHandler::InitializeInternal() {
|
Status TrickPlayHandler::InitializeInternal() {
|
||||||
|
@ -38,13 +38,13 @@ Status TrickPlayHandler::InitializeInternal() {
|
||||||
return Status(error::TRICK_PLAY_ERROR,
|
return Status(error::TRICK_PLAY_ERROR,
|
||||||
"Trick play does not have main stream");
|
"Trick play does not have main stream");
|
||||||
}
|
}
|
||||||
if (trick_play_rates_.empty()) {
|
if (trick_play_factors_.empty()) {
|
||||||
return Status(error::TRICK_PLAY_ERROR,
|
return Status(error::TRICK_PLAY_ERROR,
|
||||||
"Trick play rates are not specified.");
|
"Trick play factors are not specified.");
|
||||||
}
|
}
|
||||||
size_t num_trick_play_rates = trick_play_rates_.size();
|
size_t num_trick_play_factors = trick_play_factors_.size();
|
||||||
cached_stream_data_.resize(num_trick_play_rates);
|
cached_stream_data_.resize(num_trick_play_factors);
|
||||||
playback_rates_.resize(num_trick_play_rates, 0);
|
playback_rates_.resize(num_trick_play_factors, 0);
|
||||||
|
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ Status TrickPlayHandler::Process(
|
||||||
}
|
}
|
||||||
const VideoStreamInfo& video_stream_info =
|
const VideoStreamInfo& video_stream_info =
|
||||||
static_cast<const VideoStreamInfo&>(*stream_data->stream_info);
|
static_cast<const VideoStreamInfo&>(*stream_data->stream_info);
|
||||||
if (video_stream_info.trick_play_rate() > 0) {
|
if (video_stream_info.trick_play_factor() > 0) {
|
||||||
status.SetError(error::TRICK_PLAY_ERROR,
|
status.SetError(error::TRICK_PLAY_ERROR,
|
||||||
"This stream is alreay a trick play stream.");
|
"This stream is alreay a trick play stream.");
|
||||||
return status;
|
return status;
|
||||||
|
@ -101,10 +101,10 @@ Status TrickPlayHandler::Process(
|
||||||
if (stream_data->media_sample->is_key_frame()) {
|
if (stream_data->media_sample->is_key_frame()) {
|
||||||
// For a new key frame, some of the trick play streams may include it.
|
// For a new key frame, some of the trick play streams may include it.
|
||||||
// The cached data in those trick play streams will be processed.
|
// The cached data in those trick play streams will be processed.
|
||||||
DCHECK_EQ(trick_play_rates_.size(), cached_stream_data_.size());
|
DCHECK_EQ(trick_play_factors_.size(), cached_stream_data_.size());
|
||||||
for (size_t i = 0; i < cached_stream_data_.size(); ++i) {
|
for (size_t i = 0; i < cached_stream_data_.size(); ++i) {
|
||||||
uint32_t rate = trick_play_rates_[i];
|
uint32_t factor = trick_play_factors_[i];
|
||||||
if (total_key_frames_ % rate == 0) {
|
if (total_key_frames_ % factor == 0) {
|
||||||
// Delay processing cached stream data until receiving the second key
|
// Delay processing cached stream data until receiving the second key
|
||||||
// frame so that the GOP size could be derived.
|
// frame so that the GOP size could be derived.
|
||||||
if (!cached_stream_data_[i].empty() && total_key_frames_ > 0) {
|
if (!cached_stream_data_[i].empty() && total_key_frames_ > 0) {
|
||||||
|
@ -135,7 +135,7 @@ Status TrickPlayHandler::Process(
|
||||||
bool TrickPlayHandler::ValidateOutputStreamIndex(size_t stream_index) const {
|
bool TrickPlayHandler::ValidateOutputStreamIndex(size_t stream_index) const {
|
||||||
// Output stream index should be less than the number of trick play
|
// Output stream index should be less than the number of trick play
|
||||||
// streams + one original stream.
|
// streams + one original stream.
|
||||||
return stream_index <= trick_play_rates_.size();
|
return stream_index <= trick_play_factors_.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
|
Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
|
||||||
|
@ -143,7 +143,7 @@ Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
|
||||||
<< "Trick Play Handler should only have single input.";
|
<< "Trick Play Handler should only have single input.";
|
||||||
for (size_t i = 0; i < cached_stream_data_.size(); ++i) {
|
for (size_t i = 0; i < cached_stream_data_.size(); ++i) {
|
||||||
LOG_IF(WARNING, playback_rates_[i] == 0)
|
LOG_IF(WARNING, playback_rates_[i] == 0)
|
||||||
<< "Max playout rate for trick play rate " << trick_play_rates_[i]
|
<< "Max playout rate for trick play factor " << trick_play_factors_[i]
|
||||||
<< " is not determined. "
|
<< " is not determined. "
|
||||||
<< "Specify it as total number of frames: " << total_frames_ << ".";
|
<< "Specify it as total number of frames: " << total_frames_ << ".";
|
||||||
playback_rates_[i] = total_frames_;
|
playback_rates_[i] = total_frames_;
|
||||||
|
@ -179,16 +179,16 @@ Status TrickPlayHandler::ProcessOneStreamData(
|
||||||
size_t output_stream_index,
|
size_t output_stream_index,
|
||||||
const std::shared_ptr<StreamData>& stream_data) {
|
const std::shared_ptr<StreamData>& stream_data) {
|
||||||
size_t trick_play_index = output_stream_index - 1;
|
size_t trick_play_index = output_stream_index - 1;
|
||||||
uint32_t trick_play_rate = trick_play_rates_[trick_play_index];
|
uint32_t trick_play_factor = trick_play_factors_[trick_play_index];
|
||||||
Status status;
|
Status status;
|
||||||
switch (stream_data->stream_data_type) {
|
switch (stream_data->stream_data_type) {
|
||||||
// trick_play_rate in StreamInfo should be modified.
|
// trick_play_factor in StreamInfo should be modified.
|
||||||
case StreamDataType::kStreamInfo: {
|
case StreamDataType::kStreamInfo: {
|
||||||
const VideoStreamInfo& video_stream_info =
|
const VideoStreamInfo& video_stream_info =
|
||||||
static_cast<const VideoStreamInfo&>(*stream_data->stream_info);
|
static_cast<const VideoStreamInfo&>(*stream_data->stream_info);
|
||||||
std::shared_ptr<VideoStreamInfo> trick_play_video_stream_info(
|
std::shared_ptr<VideoStreamInfo> trick_play_video_stream_info(
|
||||||
new VideoStreamInfo(video_stream_info));
|
new VideoStreamInfo(video_stream_info));
|
||||||
trick_play_video_stream_info->set_trick_play_rate(trick_play_rate);
|
trick_play_video_stream_info->set_trick_play_factor(trick_play_factor);
|
||||||
DCHECK_GT(playback_rates_[trick_play_index], 0u);
|
DCHECK_GT(playback_rates_[trick_play_index], 0u);
|
||||||
trick_play_video_stream_info->set_playback_rate(
|
trick_play_video_stream_info->set_playback_rate(
|
||||||
playback_rates_[trick_play_index]);
|
playback_rates_[trick_play_index]);
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace media {
|
||||||
/// TrickPlayHandler is a single-input-multiple-output media handler. It creates
|
/// TrickPlayHandler is a single-input-multiple-output media handler. It creates
|
||||||
/// trick play streams from the input.
|
/// trick play streams from the input.
|
||||||
// The stream data in trick play stream is not a simple duplicate. Some
|
// The stream data in trick play stream is not a simple duplicate. Some
|
||||||
// information need to be updated, including trick_play_rate in
|
// information need to be updated, including trick_play_factor in
|
||||||
// VideoStreamInfo, the duration in MediaSample (which makes sure there is no
|
// VideoStreamInfo, the duration in MediaSample (which makes sure there is no
|
||||||
// gap between the media sample dts). Since the duration information can be
|
// gap between the media sample dts). Since the duration information can be
|
||||||
// determined after getting the next media sample, a queue is used to cache the
|
// determined after getting the next media sample, a queue is used to cache the
|
||||||
|
@ -26,7 +26,7 @@ class TrickPlayHandler : public MediaHandler {
|
||||||
~TrickPlayHandler() override;
|
~TrickPlayHandler() override;
|
||||||
|
|
||||||
void SetHandlerForMainStream(std::shared_ptr<MediaHandler> handler);
|
void SetHandlerForMainStream(std::shared_ptr<MediaHandler> handler);
|
||||||
void SetHandlerForTrickPlay(uint32_t trick_play_rate,
|
void SetHandlerForTrickPlay(uint32_t trick_play_factor,
|
||||||
std::shared_ptr<MediaHandler> handler);
|
std::shared_ptr<MediaHandler> handler);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -59,14 +59,14 @@ class TrickPlayHandler : public MediaHandler {
|
||||||
Status ProcessOneStreamData(size_t output_stream_index,
|
Status ProcessOneStreamData(size_t output_stream_index,
|
||||||
const std::shared_ptr<StreamData>& stream_data);
|
const std::shared_ptr<StreamData>& stream_data);
|
||||||
|
|
||||||
// Trick play rates. Note that there can be multiple trick play rates,
|
// Trick play factors. Note that there can be multiple trick play factors,
|
||||||
// e.g., 2, 4 and 8. That means, one input video stream will generate 3
|
// e.g., 2, 4 and 8. That means, one input video stream will generate 3
|
||||||
// output trick play streams and original stream. Three trick play streams
|
// output trick play streams and original stream. Three trick play streams
|
||||||
// are:
|
// are:
|
||||||
// [key_frame_0, key_frame_2, key_frame_4, ...]
|
// [key_frame_0, key_frame_2, key_frame_4, ...]
|
||||||
// [key_frame_0, key_frame_4, key_frame_8,...]
|
// [key_frame_0, key_frame_4, key_frame_8,...]
|
||||||
// [key_frame_0, key_frame_8, key_frame_16, ...].
|
// [key_frame_0, key_frame_8, key_frame_16, ...].
|
||||||
std::vector<uint32_t> trick_play_rates_;
|
std::vector<uint32_t> trick_play_factors_;
|
||||||
|
|
||||||
TrickPlayHandler(const TrickPlayHandler&) = delete;
|
TrickPlayHandler(const TrickPlayHandler&) = delete;
|
||||||
TrickPlayHandler& operator=(const TrickPlayHandler&) = delete;
|
TrickPlayHandler& operator=(const TrickPlayHandler&) = delete;
|
||||||
|
|
|
@ -24,8 +24,8 @@ const size_t kStreamIndex1 = 1;
|
||||||
const size_t kStreamIndex2 = 2;
|
const size_t kStreamIndex2 = 2;
|
||||||
const uint32_t kTimeScale = 800;
|
const uint32_t kTimeScale = 800;
|
||||||
const uint32_t kDuration = 200;
|
const uint32_t kDuration = 200;
|
||||||
const uint32_t kTrickPlayRates[]{1, 2};
|
const uint32_t kTrickPlayFactors[]{1, 2};
|
||||||
const uint32_t kTrickPlayRatesDecreasing[]{2, 1};
|
const uint32_t kTrickPlayFactorsDecreasing[]{2, 1};
|
||||||
const bool kEncrypted = true;
|
const bool kEncrypted = true;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ MATCHER_P5(IsTrickPlayVideoStreamInfo,
|
||||||
stream_index,
|
stream_index,
|
||||||
time_scale,
|
time_scale,
|
||||||
encrypted,
|
encrypted,
|
||||||
trick_play_rate,
|
trick_play_factor,
|
||||||
playback_rate,
|
playback_rate,
|
||||||
"") {
|
"") {
|
||||||
return arg->stream_index == stream_index &&
|
return arg->stream_index == stream_index &&
|
||||||
|
@ -42,7 +42,7 @@ MATCHER_P5(IsTrickPlayVideoStreamInfo,
|
||||||
arg->stream_info->is_encrypted() == encrypted &&
|
arg->stream_info->is_encrypted() == encrypted &&
|
||||||
arg->stream_info->stream_type() == kStreamVideo &&
|
arg->stream_info->stream_type() == kStreamVideo &&
|
||||||
static_cast<const VideoStreamInfo*>(arg->stream_info.get())
|
static_cast<const VideoStreamInfo*>(arg->stream_info.get())
|
||||||
->trick_play_rate() == trick_play_rate &&
|
->trick_play_factor() == trick_play_factor &&
|
||||||
static_cast<const VideoStreamInfo*>(arg->stream_info.get())
|
static_cast<const VideoStreamInfo*>(arg->stream_info.get())
|
||||||
->playback_rate() == playback_rate;
|
->playback_rate() == playback_rate;
|
||||||
}
|
}
|
||||||
|
@ -57,14 +57,14 @@ MATCHER_P3(IsKeyFrameMediaSample, stream_index, timestamp, duration, "") {
|
||||||
|
|
||||||
class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
||||||
public:
|
public:
|
||||||
void SetUpTrickPlayHandler(const std::vector<uint32_t>& trick_play_rates) {
|
void SetUpTrickPlayHandler(const std::vector<uint32_t>& trick_play_factors) {
|
||||||
trick_play_handler_.reset(new TrickPlayHandler());
|
trick_play_handler_.reset(new TrickPlayHandler());
|
||||||
// Use SetUpGraph to set only input handler, and use
|
// Use SetUpGraph to set only input handler, and use
|
||||||
// SetHandlerForMainStream and SetHandlerForTrickPlay for the output
|
// SetHandlerForMainStream and SetHandlerForTrickPlay for the output
|
||||||
// handlers.
|
// handlers.
|
||||||
SetUpGraph(1, 0, trick_play_handler_);
|
SetUpGraph(1, 0, trick_play_handler_);
|
||||||
trick_play_handler_->SetHandlerForMainStream(next_handler());
|
trick_play_handler_->SetHandlerForMainStream(next_handler());
|
||||||
for (uint32_t rate : trick_play_rates) {
|
for (uint32_t rate : trick_play_factors) {
|
||||||
trick_play_handler_->SetHandlerForTrickPlay(rate, next_handler());
|
trick_play_handler_->SetHandlerForTrickPlay(rate, next_handler());
|
||||||
}
|
}
|
||||||
ASSERT_OK(trick_play_handler_->Initialize());
|
ASSERT_OK(trick_play_handler_->Initialize());
|
||||||
|
@ -84,9 +84,9 @@ class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
||||||
|
|
||||||
// This test makes sure the audio stream is rejected by the trick play handler.
|
// This test makes sure the audio stream is rejected by the trick play handler.
|
||||||
TEST_F(TrickPlayHandlerTest, AudioStream) {
|
TEST_F(TrickPlayHandlerTest, AudioStream) {
|
||||||
const std::vector<uint32_t> trick_play_rates(std::begin(kTrickPlayRates),
|
const std::vector<uint32_t> trick_play_factors(std::begin(kTrickPlayFactors),
|
||||||
std::end(kTrickPlayRates));
|
std::end(kTrickPlayFactors));
|
||||||
SetUpTrickPlayHandler(trick_play_rates);
|
SetUpTrickPlayHandler(trick_play_factors);
|
||||||
|
|
||||||
Status status =
|
Status status =
|
||||||
Process(GetAudioStreamInfoStreamData(kStreamIndex0, kTimeScale));
|
Process(GetAudioStreamInfoStreamData(kStreamIndex0, kTimeScale));
|
||||||
|
@ -97,9 +97,9 @@ TEST_F(TrickPlayHandlerTest, AudioStream) {
|
||||||
// This test makes sure the trick play handler can process stream data
|
// This test makes sure the trick play handler can process stream data
|
||||||
// correctly.
|
// correctly.
|
||||||
TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||||
const std::vector<uint32_t> trick_play_rates(std::begin(kTrickPlayRates),
|
const std::vector<uint32_t> trick_play_factors(std::begin(kTrickPlayFactors),
|
||||||
std::end(kTrickPlayRates));
|
std::end(kTrickPlayFactors));
|
||||||
SetUpTrickPlayHandler(trick_play_rates);
|
SetUpTrickPlayHandler(trick_play_factors);
|
||||||
|
|
||||||
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
||||||
// The stream info is cached, so the output is empty.
|
// The stream info is cached, so the output is empty.
|
||||||
|
@ -147,11 +147,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||||
// Frame 3, key frame.
|
// Frame 3, key frame.
|
||||||
IsKeyFrameMediaSample(
|
IsKeyFrameMediaSample(
|
||||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
||||||
// Stream info, TrickPlayRate = 1.
|
// Stream info, TrickPlayFactor = 1.
|
||||||
IsTrickPlayVideoStreamInfo(
|
IsTrickPlayVideoStreamInfo(
|
||||||
kStreamIndex1, kTimeScale, !kEncrypted, kTrickPlayRates[0],
|
kStreamIndex1, kTimeScale, !kEncrypted, kTrickPlayFactors[0],
|
||||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRates[0]),
|
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactors[0]),
|
||||||
// Frame 0, TrickPlayRate = 1.
|
// Frame 0, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
||||||
kDuration * 3),
|
kDuration * 3),
|
||||||
// Frame 4.
|
// Frame 4.
|
||||||
|
@ -177,15 +177,15 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||||
// Frame 6, key frame.
|
// Frame 6, key frame.
|
||||||
IsKeyFrameMediaSample(
|
IsKeyFrameMediaSample(
|
||||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
||||||
// Frame 3, TrickPlayRate = 1.
|
// Frame 3, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex1,
|
IsKeyFrameMediaSample(kStreamIndex1,
|
||||||
kVideoStartTimestamp + kDuration * 3,
|
kVideoStartTimestamp + kDuration * 3,
|
||||||
kDuration * 3),
|
kDuration * 3),
|
||||||
// Stream info, TrickPlayRate = 2.
|
// Stream info, TrickPlayFactor = 2.
|
||||||
IsTrickPlayVideoStreamInfo(
|
IsTrickPlayVideoStreamInfo(
|
||||||
kStreamIndex2, kTimeScale, !kEncrypted, kTrickPlayRates[1],
|
kStreamIndex2, kTimeScale, !kEncrypted, kTrickPlayFactors[1],
|
||||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRates[1]),
|
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactors[1]),
|
||||||
// Frame 0, TrickPlayRate = 2.
|
// Frame 0, TrickPlayFactor = 2.
|
||||||
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
||||||
kDuration * 6),
|
kDuration * 6),
|
||||||
// Frame 7.
|
// Frame 7.
|
||||||
|
@ -196,11 +196,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||||
ASSERT_OK(FlushStream(0));
|
ASSERT_OK(FlushStream(0));
|
||||||
EXPECT_THAT(GetOutputStreamDataVector(),
|
EXPECT_THAT(GetOutputStreamDataVector(),
|
||||||
ElementsAre(
|
ElementsAre(
|
||||||
// Frame 6, TrickPlayRate = 1.
|
// Frame 6, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex1,
|
IsKeyFrameMediaSample(kStreamIndex1,
|
||||||
kVideoStartTimestamp + kDuration * 6,
|
kVideoStartTimestamp + kDuration * 6,
|
||||||
kDuration * 2),
|
kDuration * 2),
|
||||||
// Frame 6, TrickPlayRate = 2.
|
// Frame 6, TrickPlayFactor = 2.
|
||||||
IsKeyFrameMediaSample(kStreamIndex2,
|
IsKeyFrameMediaSample(kStreamIndex2,
|
||||||
kVideoStartTimestamp + kDuration * 6,
|
kVideoStartTimestamp + kDuration * 6,
|
||||||
kDuration * 2)));
|
kDuration * 2)));
|
||||||
|
@ -212,12 +212,12 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test makes sure the trick play handler can process stream data
|
// This test makes sure the trick play handler can process stream data
|
||||||
// correctly with a decreasing order of trick play rates.
|
// correctly with a decreasing order of trick play factors.
|
||||||
TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayFactors) {
|
||||||
const std::vector<uint32_t> trick_play_rates(
|
const std::vector<uint32_t> trick_play_factors(
|
||||||
std::begin(kTrickPlayRatesDecreasing),
|
std::begin(kTrickPlayFactorsDecreasing),
|
||||||
std::end(kTrickPlayRatesDecreasing));
|
std::end(kTrickPlayFactorsDecreasing));
|
||||||
SetUpTrickPlayHandler(trick_play_rates);
|
SetUpTrickPlayHandler(trick_play_factors);
|
||||||
|
|
||||||
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
||||||
// The stream info is cached, so the output is empty.
|
// The stream info is cached, so the output is empty.
|
||||||
|
@ -265,12 +265,12 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
||||||
// Frame 3, key frame.
|
// Frame 3, key frame.
|
||||||
IsKeyFrameMediaSample(
|
IsKeyFrameMediaSample(
|
||||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
||||||
// Stream info, TrickPlayRate = 1.
|
// Stream info, TrickPlayFactor = 1.
|
||||||
IsTrickPlayVideoStreamInfo(
|
IsTrickPlayVideoStreamInfo(
|
||||||
kStreamIndex2, kTimeScale, !kEncrypted,
|
kStreamIndex2, kTimeScale, !kEncrypted,
|
||||||
kTrickPlayRatesDecreasing[1],
|
kTrickPlayFactorsDecreasing[1],
|
||||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRatesDecreasing[1]),
|
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactorsDecreasing[1]),
|
||||||
// Frame 0, TrickPlayRate = 1.
|
// Frame 0, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
||||||
kDuration * 3),
|
kDuration * 3),
|
||||||
// Frame 4.
|
// Frame 4.
|
||||||
|
@ -296,15 +296,15 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
||||||
// Frame 6, key frame.
|
// Frame 6, key frame.
|
||||||
IsKeyFrameMediaSample(
|
IsKeyFrameMediaSample(
|
||||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
||||||
// Stream info, TrickPlayRate = 2.
|
// Stream info, TrickPlayFactor = 2.
|
||||||
IsTrickPlayVideoStreamInfo(
|
IsTrickPlayVideoStreamInfo(
|
||||||
kStreamIndex1, kTimeScale, !kEncrypted,
|
kStreamIndex1, kTimeScale, !kEncrypted,
|
||||||
kTrickPlayRatesDecreasing[0],
|
kTrickPlayFactorsDecreasing[0],
|
||||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRatesDecreasing[0]),
|
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactorsDecreasing[0]),
|
||||||
// Frame 0, TrickPlayRate = 2.
|
// Frame 0, TrickPlayFactor = 2.
|
||||||
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
||||||
kDuration * 6),
|
kDuration * 6),
|
||||||
// Frame 3, TrickPlayRate = 1.
|
// Frame 3, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex2,
|
IsKeyFrameMediaSample(kStreamIndex2,
|
||||||
kVideoStartTimestamp + kDuration * 3,
|
kVideoStartTimestamp + kDuration * 3,
|
||||||
kDuration * 3),
|
kDuration * 3),
|
||||||
|
@ -316,11 +316,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
||||||
ASSERT_OK(FlushStream(0));
|
ASSERT_OK(FlushStream(0));
|
||||||
EXPECT_THAT(GetOutputStreamDataVector(),
|
EXPECT_THAT(GetOutputStreamDataVector(),
|
||||||
ElementsAre(
|
ElementsAre(
|
||||||
// Frame 6, TrickPlayRate = 2.
|
// Frame 6, TrickPlayFactor = 2.
|
||||||
IsKeyFrameMediaSample(kStreamIndex1,
|
IsKeyFrameMediaSample(kStreamIndex1,
|
||||||
kVideoStartTimestamp + kDuration * 6,
|
kVideoStartTimestamp + kDuration * 6,
|
||||||
kDuration * 2),
|
kDuration * 2),
|
||||||
// Frame 6, TrickPlayRate = 1.
|
// Frame 6, TrickPlayFactor = 1.
|
||||||
IsKeyFrameMediaSample(kStreamIndex2,
|
IsKeyFrameMediaSample(kStreamIndex2,
|
||||||
kVideoStartTimestamp + kDuration * 6,
|
kVideoStartTimestamp + kDuration * 6,
|
||||||
kDuration * 2)));
|
kDuration * 2)));
|
||||||
|
|
|
@ -276,7 +276,7 @@ AdaptationSet* DashIopMpdNotifier::NewAdaptationSet(
|
||||||
new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (media_info.video_info().trick_play_rate() > 0) {
|
if (media_info.video_info().trick_play_factor() > 0) {
|
||||||
uint32_t trick_play_reference_id = 0;
|
uint32_t trick_play_reference_id = 0;
|
||||||
if (!FindOriginalAdaptationSetForTrickPlay(media_info,
|
if (!FindOriginalAdaptationSetForTrickPlay(media_info,
|
||||||
&trick_play_reference_id)) {
|
&trick_play_reference_id)) {
|
||||||
|
@ -294,7 +294,7 @@ bool DashIopMpdNotifier::FindOriginalAdaptationSetForTrickPlay(
|
||||||
const MediaInfo& media_info,
|
const MediaInfo& media_info,
|
||||||
uint32_t* main_adaptation_set_id) {
|
uint32_t* main_adaptation_set_id) {
|
||||||
MediaInfo media_info_no_trickplay = media_info;
|
MediaInfo media_info_no_trickplay = media_info;
|
||||||
media_info_no_trickplay.mutable_video_info()->clear_trick_play_rate();
|
media_info_no_trickplay.mutable_video_info()->clear_trick_play_factor();
|
||||||
std::string key = GetAdaptationSetKey(media_info_no_trickplay);
|
std::string key = GetAdaptationSetKey(media_info_no_trickplay);
|
||||||
const std::list<AdaptationSet*>& adaptation_sets =
|
const std::list<AdaptationSet*>& adaptation_sets =
|
||||||
adaptation_set_list_map_[key];
|
adaptation_set_list_map_[key];
|
||||||
|
|
|
@ -167,7 +167,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewContainerForTrickPlay) {
|
||||||
" frame_duration: 100\n"
|
" frame_duration: 100\n"
|
||||||
" pixel_width: 1\n"
|
" pixel_width: 1\n"
|
||||||
" pixel_height: 1\n"
|
" pixel_height: 1\n"
|
||||||
" trick_play_rate: 2\n"
|
" trick_play_factor: 2\n"
|
||||||
" playback_rate: 10\n"
|
" playback_rate: 10\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
|
|
@ -41,9 +41,9 @@ message MediaInfo {
|
||||||
optional uint32 pixel_width = 7;
|
optional uint32 pixel_width = 7;
|
||||||
optional uint32 pixel_height = 8;
|
optional uint32 pixel_height = 8;
|
||||||
|
|
||||||
// trick_play_rate: sample rate of the key frame from the original stream.
|
// trick_play_factor: sample rate of the key frame from the original stream.
|
||||||
// e.g., 1 means every key frame, 2 means every two key frames.
|
// e.g., 1 means every key frame, 2 means every two key frames.
|
||||||
optional uint32 trick_play_rate = 9;
|
optional uint32 trick_play_factor = 9;
|
||||||
// playback_rate: the playout capability (e.g., 4x, 8x, 16x fast foward) of
|
// playback_rate: the playout capability (e.g., 4x, 8x, 16x fast foward) of
|
||||||
// the trick play stream.
|
// the trick play stream.
|
||||||
optional uint32 playback_rate = 10;
|
optional uint32 playback_rate = 10;
|
||||||
|
|
|
@ -137,9 +137,9 @@ std::string GetAdaptationSetKey(const MediaInfo& media_info) {
|
||||||
key.append(GetLanguage(media_info));
|
key.append(GetLanguage(media_info));
|
||||||
|
|
||||||
// Trick play streams of the same original stream, but possibly with
|
// Trick play streams of the same original stream, but possibly with
|
||||||
// different trick_play_rates, belong to the same trick play AdaptationSet.
|
// different trick_play_factors, belong to the same trick play AdaptationSet.
|
||||||
if (media_info.has_video_info() &&
|
if (media_info.has_video_info() &&
|
||||||
media_info.video_info().trick_play_rate() > 0) {
|
media_info.video_info().trick_play_factor() > 0) {
|
||||||
key.append(":trick_play");
|
key.append(":trick_play");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue