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
|
||||
// are sorted so that for the same input and stream_selector, the main
|
||||
// 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) {
|
||||
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));
|
||||
if (trick_play_handler->IsConnected())
|
||||
continue;
|
||||
|
|
|
@ -30,7 +30,7 @@ enum FieldType {
|
|||
kHlsNameField,
|
||||
kHlsGroupIdField,
|
||||
kHlsPlaylistNameField,
|
||||
kTrickPlayRateField,
|
||||
kTrickPlayFactorField,
|
||||
};
|
||||
|
||||
struct FieldNameToTypeMapping {
|
||||
|
@ -58,7 +58,8 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
|
|||
{"hls_name", kHlsNameField},
|
||||
{"hls_group_id", kHlsGroupIdField},
|
||||
{"playlist_name", kHlsPlaylistNameField},
|
||||
{"trick_play_rate", kTrickPlayRateField},
|
||||
{"trick_play_factor", kTrickPlayFactorField},
|
||||
{"tpf", kTrickPlayFactorField},
|
||||
};
|
||||
|
||||
FieldType GetFieldType(const std::string& field_name) {
|
||||
|
@ -143,18 +144,18 @@ bool InsertStreamDescriptor(const std::string& descriptor_string,
|
|||
descriptor.hls_playlist_name = iter->second;
|
||||
break;
|
||||
}
|
||||
case kTrickPlayRateField: {
|
||||
unsigned rate;
|
||||
if (!base::StringToUint(iter->second, &rate)) {
|
||||
LOG(ERROR) << "Non-numeric trick play rate " << iter->second
|
||||
case kTrickPlayFactorField: {
|
||||
unsigned factor;
|
||||
if (!base::StringToUint(iter->second, &factor)) {
|
||||
LOG(ERROR) << "Non-numeric trick play factor " << iter->second
|
||||
<< " specified.";
|
||||
return false;
|
||||
}
|
||||
if (rate == 0) {
|
||||
LOG(ERROR) << "Stream trick_play_rate should be > 0.";
|
||||
if (factor == 0) {
|
||||
LOG(ERROR) << "Stream trick_play_factor should be > 0.";
|
||||
return false;
|
||||
}
|
||||
descriptor.trick_play_rate = rate;
|
||||
descriptor.trick_play_factor = factor;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -33,7 +33,7 @@ struct StreamDescriptor {
|
|||
std::string hls_name;
|
||||
std::string hls_group_id;
|
||||
std::string hls_playlist_name;
|
||||
uint32_t trick_play_rate = 0;
|
||||
uint32_t trick_play_factor = 0;
|
||||
};
|
||||
|
||||
class StreamDescriptorCompareFn {
|
||||
|
@ -41,8 +41,8 @@ class StreamDescriptorCompareFn {
|
|||
bool operator()(const StreamDescriptor& a, const StreamDescriptor& b) {
|
||||
if (a.input == b.input) {
|
||||
if (a.stream_selector == b.stream_selector)
|
||||
// Stream with high trick_play_rate is at the beginning.
|
||||
return a.trick_play_rate > b.trick_play_rate;
|
||||
// Stream with high trick_play_factor is at the beginning.
|
||||
return a.trick_play_factor > b.trick_play_factor;
|
||||
else
|
||||
return a.stream_selector < b.stream_selector;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ class PackagerAppTest(unittest.TestCase):
|
|||
' width: 640\n'
|
||||
' height: 360\n'
|
||||
' pixel_aspect_ratio: 1:1\n'
|
||||
' trick_play_rate: 0\n'
|
||||
' trick_play_factor: 0\n'
|
||||
' nalu_length_size: 4\n\n'
|
||||
'Stream [1] type: Audio\n'
|
||||
' codec_string: mp4a.40.2\n'
|
||||
|
@ -103,7 +103,7 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
def testPackageAudioVideoWithTrickPlay(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1']),
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1']),
|
||||
self._GetFlags())
|
||||
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
||||
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
||||
|
@ -112,8 +112,8 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
def testPackageAudioVideoWithTwoTrickPlay(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1',
|
||||
'video,trick_play_rate=2']),
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1',
|
||||
'video,trick_play_factor=2']),
|
||||
self._GetFlags())
|
||||
self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4')
|
||||
self._DiffGold(self.output[1], 'bear-640x360-v-golden.mp4')
|
||||
|
@ -124,15 +124,15 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
def testPackageAudioVideoWithTwoTrickPlayDecreasingRate(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=2',
|
||||
'video,trick_play_rate=1']),
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_factor=2',
|
||||
'video,trick_play_factor=1']),
|
||||
self._GetFlags())
|
||||
self._DiffGold(self.output[0], 'bear-640x360-a-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[3], 'bear-640x360-v-trick-1-golden.mp4')
|
||||
# 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,
|
||||
'bear-640x360-av-trick-1-trick-2-golden.mpd')
|
||||
|
||||
|
@ -242,7 +242,7 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
def testPackageWithEncryptionAndTrickPlay(self):
|
||||
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._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
||||
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
||||
|
@ -256,8 +256,8 @@ class PackagerAppTest(unittest.TestCase):
|
|||
# play stream.
|
||||
def testPackageWithEncryptionAndTwoTrickPlays(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_rate=1',
|
||||
'video,trick_play_rate=2']),
|
||||
self._GetStreams(['audio', 'video', 'video,trick_play_factor=1',
|
||||
'video,trick_play_factor=2']),
|
||||
self._GetFlags(encryption=True))
|
||||
self._DiffGold(self.output[0], 'bear-640x360-a-cenc-golden.mp4')
|
||||
self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4')
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</ContentProtection>
|
||||
<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">
|
||||
<BaseURL>output_video_trick_play_rate_1.mp4</BaseURL>
|
||||
<BaseURL>output_video_trick_play_factor_1.mp4</BaseURL>
|
||||
<SegmentBase indexRange="1091-1158" timescale="30000">
|
||||
<Initialization range="0-1090"/>
|
||||
</SegmentBase>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<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"/>
|
||||
<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">
|
||||
<Initialization range="0-822"/>
|
||||
</SegmentBase>
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
</ContentProtection>
|
||||
<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">
|
||||
<BaseURL>output_video_trick_play_rate_2.mp4</BaseURL>
|
||||
<BaseURL>output_video_trick_play_factor_2.mp4</BaseURL>
|
||||
<SegmentBase indexRange="1091-1146" timescale="30000">
|
||||
<Initialization range="0-1090"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
<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">
|
||||
<Initialization range="0-1090"/>
|
||||
</SegmentBase>
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
<AdaptationSet id="1" contentType="video" width="640" height="360" maxFrameRate="30000/30030" par="16:9">
|
||||
<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">
|
||||
<BaseURL>output_video_trick_play_rate_2.mp4</BaseURL>
|
||||
<BaseURL>output_video_trick_play_factor_2.mp4</BaseURL>
|
||||
<SegmentBase indexRange="823-878" timescale="30000">
|
||||
<Initialization range="0-822"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
<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">
|
||||
<Initialization range="0-822"/>
|
||||
</SegmentBase>
|
||||
|
|
|
@ -27,7 +27,7 @@ const uint16_t kWidth = 10u;
|
|||
const uint16_t kHeight = 20u;
|
||||
const uint32_t kPixelWidth = 2u;
|
||||
const uint32_t kPixelHeight = 3u;
|
||||
const int16_t kTrickPlayRate = 0;
|
||||
const int16_t kTrickPlayFactor = 0;
|
||||
const uint8_t kNaluLengthSize = 1u;
|
||||
const bool kEncrypted = true;
|
||||
|
||||
|
@ -156,7 +156,7 @@ std::shared_ptr<StreamInfo> MediaHandlerTestBase::GetMockStreamInfo(
|
|||
return std::shared_ptr<StreamInfo>(new VideoStreamInfo(
|
||||
kTrackId, time_scale, kDuration, codec, H26xStreamFormat::kUnSpecified,
|
||||
kCodecString, kCodecConfig, sizeof(kCodecConfig), kWidth, kHeight,
|
||||
kPixelWidth, kPixelHeight, kTrickPlayRate, kNaluLengthSize, kLanguage,
|
||||
kPixelWidth, kPixelHeight, kTrickPlayFactor, kNaluLengthSize, kLanguage,
|
||||
!kEncrypted));
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -48,7 +48,7 @@ VideoStreamInfo::VideoStreamInfo(int track_id,
|
|||
uint16_t height,
|
||||
uint32_t pixel_width,
|
||||
uint32_t pixel_height,
|
||||
uint32_t trick_play_rate,
|
||||
uint32_t trick_play_factor,
|
||||
uint8_t nalu_length_size,
|
||||
const std::string& language,
|
||||
bool is_encrypted)
|
||||
|
@ -67,7 +67,7 @@ VideoStreamInfo::VideoStreamInfo(int track_id,
|
|||
height_(height),
|
||||
pixel_width_(pixel_width),
|
||||
pixel_height_(pixel_height),
|
||||
trick_play_rate_(trick_play_rate),
|
||||
trick_play_factor_(trick_play_factor),
|
||||
nalu_length_size_(nalu_length_size) {}
|
||||
|
||||
VideoStreamInfo::~VideoStreamInfo() {}
|
||||
|
@ -82,9 +82,9 @@ bool VideoStreamInfo::IsValidConfig() const {
|
|||
std::string VideoStreamInfo::ToString() const {
|
||||
return base::StringPrintf(
|
||||
"%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(),
|
||||
width_, height_, pixel_width_, pixel_height_, trick_play_rate_,
|
||||
width_, height_, pixel_width_, pixel_height_, trick_play_factor_,
|
||||
nalu_length_size_);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class VideoStreamInfo : public StreamInfo {
|
|||
uint16_t height,
|
||||
uint32_t pixel_width,
|
||||
uint32_t pixel_height,
|
||||
uint32_t trick_play_rate,
|
||||
uint32_t trick_play_factor,
|
||||
uint8_t nalu_length_size,
|
||||
const std::string& language,
|
||||
bool is_encrypted);
|
||||
|
@ -62,7 +62,7 @@ class VideoStreamInfo : public StreamInfo {
|
|||
/// @return 0 if unknown.
|
||||
uint32_t pixel_height() const { return pixel_height_; }
|
||||
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_; }
|
||||
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_pixel_width(uint32_t pixel_width) { pixel_width_ = pixel_width; }
|
||||
void set_pixel_height(uint32_t pixel_height) { pixel_height_ = pixel_height; }
|
||||
void set_trick_play_rate(uint32_t trick_play_rate) {
|
||||
trick_play_rate_ = trick_play_rate;
|
||||
void set_trick_play_factor(uint32_t trick_play_factor) {
|
||||
trick_play_factor_ = trick_play_factor;
|
||||
}
|
||||
void set_playback_rate(uint32_t playback_rate) {
|
||||
playback_rate_ = playback_rate;
|
||||
|
@ -90,7 +90,7 @@ class VideoStreamInfo : public StreamInfo {
|
|||
// 0 means unknown.
|
||||
uint32_t pixel_width_;
|
||||
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
|
||||
// playout capabilities
|
||||
|
@ -99,8 +99,8 @@ class VideoStreamInfo : public StreamInfo {
|
|||
// 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
|
||||
// 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
|
||||
// 3, the key frames are in this trick play stream are [frame_0, frame_30,
|
||||
// example, if the video stream has GOP size of 10 and the trick play factor
|
||||
// is 3, the key frames are in this trick play stream are [frame_0, frame_30,
|
||||
// frame_60, ...]. Then the playback_rate is 30.
|
||||
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());
|
||||
}
|
||||
|
||||
if (video_stream_info->trick_play_rate() > 0) {
|
||||
video_info->set_trick_play_rate(video_stream_info->trick_play_rate());
|
||||
if (video_stream_info->trick_play_factor() > 0) {
|
||||
video_info->set_trick_play_factor(video_stream_info->trick_play_factor());
|
||||
CHECK_GT(video_stream_info->playback_rate(), 0u)
|
||||
<< "Max playout rate should be > 0 for trick play streams.";
|
||||
video_info->set_playback_rate(video_stream_info->playback_rate());
|
||||
|
|
|
@ -21,7 +21,7 @@ std::shared_ptr<StreamInfo> CreateVideoStreamInfo(
|
|||
H26xStreamFormat::kUnSpecified, param.codec_string,
|
||||
param.codec_config.data(), param.codec_config.size(), param.width,
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ const uint32_t kWidth = 1280;
|
|||
const uint32_t kHeight = 720;
|
||||
const uint32_t kPixelWidth = 1;
|
||||
const uint32_t kPixelHeight = 1;
|
||||
const uint16_t kTrickPlayRate = 1;
|
||||
const uint16_t kTrickPlayFactor = 1;
|
||||
const uint8_t kNaluLengthSize = 1;
|
||||
const bool kIsEncrypted = false;
|
||||
|
||||
|
@ -118,7 +118,7 @@ std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(Codec codec) {
|
|||
kTrackId, kTimeScale, kDuration, codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
return stream_info;
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ TEST_F(PesPacketGeneratorTest, TimeStampScaling) {
|
|||
kTrackId, kTestTimescale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kVideoExtraData,
|
||||
arraysize(kVideoExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_TRUE(generator_.Initialize(*stream_info));
|
||||
|
||||
EXPECT_EQ(0u, generator_.NumberOfReadyPesPackets());
|
||||
|
|
|
@ -41,7 +41,7 @@ const uint32_t kWidth = 1280;
|
|||
const uint32_t kHeight = 720;
|
||||
const uint32_t kPixelWidth = 1;
|
||||
const uint32_t kPixelHeight = 1;
|
||||
const uint16_t kTrickPlayRate = 1;
|
||||
const uint16_t kTrickPlayFactor = 1;
|
||||
const uint8_t kNaluLengthSize = 1;
|
||||
const bool kIsEncrypted = false;
|
||||
|
||||
|
@ -100,7 +100,7 @@ TEST_F(TsSegmenterTest, Initialize) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options, nullptr);
|
||||
|
@ -121,7 +121,7 @@ TEST_F(TsSegmenterTest, AddSample) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options, nullptr);
|
||||
|
@ -173,7 +173,7 @@ TEST_F(TsSegmenterTest, PassedSegmentDuration) {
|
|||
kTrackId, kInputTimescale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
|
||||
|
@ -268,7 +268,7 @@ TEST_F(TsSegmenterTest, InitializeThenFinalize) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options, nullptr);
|
||||
|
@ -297,7 +297,7 @@ TEST_F(TsSegmenterTest, FinalizeSegment) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
options.segment_template = "file$Number$.ts";
|
||||
TsSegmenter segmenter(options, nullptr);
|
||||
|
@ -325,7 +325,7 @@ TEST_F(TsSegmenterTest, EncryptedSample) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
MuxerOptions options;
|
||||
|
||||
options.segment_template = "file$Number$.ts";
|
||||
|
|
|
@ -39,7 +39,7 @@ const uint32_t kWidth = 1280;
|
|||
const uint32_t kHeight = 720;
|
||||
const uint32_t kPixelWidth = 1;
|
||||
const uint32_t kPixelHeight = 1;
|
||||
const uint16_t kTrickPlayRate = 1;
|
||||
const uint16_t kTrickPlayFactor = 1;
|
||||
const uint8_t kNaluLengthSize = 1;
|
||||
const bool kIsEncrypted = false;
|
||||
|
||||
|
@ -161,7 +161,7 @@ TEST_F(TsWriterTest, InitializeVideoH264) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ TEST_F(TsWriterTest, InitializeVideoNonH264) {
|
|||
kTrackId, kTimeScale, kDuration, Codec::kCodecVP9,
|
||||
H26xStreamFormat::kUnSpecified, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_FALSE(ts_writer_.Initialize(*stream_info));
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ TEST_F(TsWriterTest, ClearH264Psi) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||
|
||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||
|
@ -287,7 +287,7 @@ TEST_F(TsWriterTest, ClearLeadH264Pmt) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||
|
||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||
|
@ -317,7 +317,7 @@ TEST_F(TsWriterTest, EncryptedSegmentsH264Pmt) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
arraysize(kExtraData), kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, kIsEncrypted));
|
||||
EXPECT_TRUE(ts_writer_.Initialize(*stream_info));
|
||||
|
||||
ts_writer_.SetProgramMapTableWriterForTesting(std::move(mock_pmt_writer));
|
||||
|
@ -406,7 +406,7 @@ TEST_F(TsWriterTest, AddPesPacket) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
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_.NewSegment(test_file_name_));
|
||||
|
||||
|
@ -472,7 +472,7 @@ TEST_F(TsWriterTest, BigPesPacket) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
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_.NewSegment(test_file_name_));
|
||||
|
||||
|
@ -509,7 +509,7 @@ TEST_F(TsWriterTest, PesPtsZeroNoDts) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
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_.NewSegment(test_file_name_));
|
||||
|
||||
|
@ -570,7 +570,7 @@ TEST_F(TsWriterTest, TsPacketPayload183Bytes) {
|
|||
kTrackId, kTimeScale, kDuration, kH264Codec,
|
||||
H26xStreamFormat::kAnnexbByteStream, kCodecString, kExtraData,
|
||||
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_.NewSegment(test_file_name_));
|
||||
|
||||
|
|
|
@ -590,7 +590,7 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
|||
entry.codec_configuration.data.data(),
|
||||
entry.codec_configuration.data.size(), coded_width, coded_height,
|
||||
pixel_width, pixel_height,
|
||||
0, // trick_play_rate
|
||||
0, // trick_play_factor
|
||||
nalu_length_size, track->media.header.language.code, is_encrypted));
|
||||
|
||||
// Set pssh raw data if it has.
|
||||
|
|
|
@ -31,7 +31,7 @@ const uint16_t kWidth = 100;
|
|||
const uint16_t kHeight = 100;
|
||||
const uint16_t kPixelWidth = 100;
|
||||
const uint16_t kPixelHeight = 100;
|
||||
const int16_t kTrickPlayRate = 1;
|
||||
const int16_t kTrickPlayFactor = 1;
|
||||
const uint8_t kNaluLengthSize = 0;
|
||||
|
||||
} // namespace
|
||||
|
@ -82,10 +82,10 @@ MuxerOptions SegmentTestBase::CreateMuxerOptions() const {
|
|||
}
|
||||
|
||||
VideoStreamInfo* SegmentTestBase::CreateVideoStreamInfo() const {
|
||||
return new VideoStreamInfo(kTrackId, kTimeScale, kDuration, kCodec,
|
||||
H26xStreamFormat::kUnSpecified, kCodecString, NULL,
|
||||
0, kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayRate, kNaluLengthSize, kLanguage, false);
|
||||
return new VideoStreamInfo(
|
||||
kTrackId, kTimeScale, kDuration, kCodec, H26xStreamFormat::kUnSpecified,
|
||||
kCodecString, NULL, 0, kWidth, kHeight, kPixelWidth, kPixelHeight,
|
||||
kTrickPlayFactor, kNaluLengthSize, kLanguage, false);
|
||||
}
|
||||
|
||||
std::string SegmentTestBase::OutputFileName() const {
|
||||
|
|
|
@ -91,7 +91,7 @@ const uint16_t kWidth = 320u;
|
|||
const uint16_t kHeight = 180u;
|
||||
const uint32_t kPixelWidth = 1u;
|
||||
const uint32_t kPixelHeight = 1u;
|
||||
const int16_t kTrickPlayRate = 0u;
|
||||
const int16_t kTrickPlayFactor = 0u;
|
||||
const uint8_t kNaluLengthSize = 0u;
|
||||
|
||||
// Test duration defaults must differ from parser estimation defaults to know
|
||||
|
@ -350,7 +350,7 @@ class WebMClusterParserTest : public testing::Test {
|
|||
kHeight,
|
||||
kPixelWidth,
|
||||
kPixelHeight,
|
||||
kTrickPlayRate,
|
||||
kTrickPlayFactor,
|
||||
kNaluLengthSize,
|
||||
kLanguage,
|
||||
!kEncrypted)),
|
||||
|
|
|
@ -574,7 +574,7 @@ bool WvmMediaParser::ParseIndexEntry() {
|
|||
}
|
||||
|
||||
uint64_t track_duration = 0;
|
||||
uint32_t trick_play_rate = 0;
|
||||
uint32_t trick_play_factor = 0;
|
||||
uint32_t sampling_frequency = kDefaultSamplingFrequency;
|
||||
uint32_t time_scale = kMpeg2ClockRate;
|
||||
uint16_t video_width = 0;
|
||||
|
@ -680,8 +680,8 @@ bool WvmMediaParser::ParseIndexEntry() {
|
|||
case TrackDuration:
|
||||
track_duration = value;
|
||||
break;
|
||||
case TrackTrickPlayRate:
|
||||
trick_play_rate = value;
|
||||
case TrackTrickPlayFactor:
|
||||
trick_play_factor = value;
|
||||
break;
|
||||
case VideoStreamId:
|
||||
video_pes_stream_id = value;
|
||||
|
@ -743,7 +743,7 @@ bool WvmMediaParser::ParseIndexEntry() {
|
|||
stream_id_count_, time_scale, track_duration, kCodecH264,
|
||||
byte_to_unit_stream_converter_.stream_format(), std::string(),
|
||||
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(),
|
||||
decryption_key_source_ ? false : true));
|
||||
program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
|
||||
|
|
|
@ -69,7 +69,7 @@ class WvmMediaParser : public MediaParser {
|
|||
TrackSize = 2,
|
||||
TrackDuration = 3,
|
||||
TrackBitRate = 4,
|
||||
TrackTrickPlayRate = 5,
|
||||
TrackTrickPlayFactor = 5,
|
||||
TrackAdaptationInterval = 6,
|
||||
TrackFlags = 7,
|
||||
VideoType = 8,
|
||||
|
|
|
@ -26,11 +26,11 @@ void TrickPlayHandler::SetHandlerForMainStream(
|
|||
}
|
||||
|
||||
void TrickPlayHandler::SetHandlerForTrickPlay(
|
||||
uint32_t trick_play_rate,
|
||||
uint32_t trick_play_factor,
|
||||
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.
|
||||
SetHandler(trick_play_rates_.size(), std::move(handler));
|
||||
SetHandler(trick_play_factors_.size(), std::move(handler));
|
||||
}
|
||||
|
||||
Status TrickPlayHandler::InitializeInternal() {
|
||||
|
@ -38,13 +38,13 @@ Status TrickPlayHandler::InitializeInternal() {
|
|||
return Status(error::TRICK_PLAY_ERROR,
|
||||
"Trick play does not have main stream");
|
||||
}
|
||||
if (trick_play_rates_.empty()) {
|
||||
if (trick_play_factors_.empty()) {
|
||||
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();
|
||||
cached_stream_data_.resize(num_trick_play_rates);
|
||||
playback_rates_.resize(num_trick_play_rates, 0);
|
||||
size_t num_trick_play_factors = trick_play_factors_.size();
|
||||
cached_stream_data_.resize(num_trick_play_factors);
|
||||
playback_rates_.resize(num_trick_play_factors, 0);
|
||||
|
||||
return Status::OK;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ Status TrickPlayHandler::Process(
|
|||
}
|
||||
const VideoStreamInfo& video_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,
|
||||
"This stream is alreay a trick play stream.");
|
||||
return status;
|
||||
|
@ -101,10 +101,10 @@ Status TrickPlayHandler::Process(
|
|||
if (stream_data->media_sample->is_key_frame()) {
|
||||
// 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.
|
||||
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) {
|
||||
uint32_t rate = trick_play_rates_[i];
|
||||
if (total_key_frames_ % rate == 0) {
|
||||
uint32_t factor = trick_play_factors_[i];
|
||||
if (total_key_frames_ % factor == 0) {
|
||||
// Delay processing cached stream data until receiving the second key
|
||||
// frame so that the GOP size could be derived.
|
||||
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 {
|
||||
// Output stream index should be less than the number of trick play
|
||||
// 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) {
|
||||
|
@ -143,7 +143,7 @@ Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
|
|||
<< "Trick Play Handler should only have single input.";
|
||||
for (size_t i = 0; i < cached_stream_data_.size(); ++i) {
|
||||
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. "
|
||||
<< "Specify it as total number of frames: " << total_frames_ << ".";
|
||||
playback_rates_[i] = total_frames_;
|
||||
|
@ -179,16 +179,16 @@ Status TrickPlayHandler::ProcessOneStreamData(
|
|||
size_t output_stream_index,
|
||||
const std::shared_ptr<StreamData>& stream_data) {
|
||||
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;
|
||||
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: {
|
||||
const VideoStreamInfo& video_stream_info =
|
||||
static_cast<const VideoStreamInfo&>(*stream_data->stream_info);
|
||||
std::shared_ptr<VideoStreamInfo> trick_play_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);
|
||||
trick_play_video_stream_info->set_playback_rate(
|
||||
playback_rates_[trick_play_index]);
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace media {
|
|||
/// TrickPlayHandler is a single-input-multiple-output media handler. It creates
|
||||
/// trick play streams from the input.
|
||||
// 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
|
||||
// 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
|
||||
|
@ -26,7 +26,7 @@ class TrickPlayHandler : public MediaHandler {
|
|||
~TrickPlayHandler() override;
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
|
@ -59,14 +59,14 @@ class TrickPlayHandler : public MediaHandler {
|
|||
Status ProcessOneStreamData(size_t output_stream_index,
|
||||
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
|
||||
// output trick play streams and original stream. Three trick play streams
|
||||
// are:
|
||||
// [key_frame_0, key_frame_2, key_frame_4, ...]
|
||||
// [key_frame_0, key_frame_4, key_frame_8,...]
|
||||
// [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& operator=(const TrickPlayHandler&) = delete;
|
||||
|
|
|
@ -24,8 +24,8 @@ const size_t kStreamIndex1 = 1;
|
|||
const size_t kStreamIndex2 = 2;
|
||||
const uint32_t kTimeScale = 800;
|
||||
const uint32_t kDuration = 200;
|
||||
const uint32_t kTrickPlayRates[]{1, 2};
|
||||
const uint32_t kTrickPlayRatesDecreasing[]{2, 1};
|
||||
const uint32_t kTrickPlayFactors[]{1, 2};
|
||||
const uint32_t kTrickPlayFactorsDecreasing[]{2, 1};
|
||||
const bool kEncrypted = true;
|
||||
} // namespace
|
||||
|
||||
|
@ -33,7 +33,7 @@ MATCHER_P5(IsTrickPlayVideoStreamInfo,
|
|||
stream_index,
|
||||
time_scale,
|
||||
encrypted,
|
||||
trick_play_rate,
|
||||
trick_play_factor,
|
||||
playback_rate,
|
||||
"") {
|
||||
return arg->stream_index == stream_index &&
|
||||
|
@ -42,7 +42,7 @@ MATCHER_P5(IsTrickPlayVideoStreamInfo,
|
|||
arg->stream_info->is_encrypted() == encrypted &&
|
||||
arg->stream_info->stream_type() == kStreamVideo &&
|
||||
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())
|
||||
->playback_rate() == playback_rate;
|
||||
}
|
||||
|
@ -57,14 +57,14 @@ MATCHER_P3(IsKeyFrameMediaSample, stream_index, timestamp, duration, "") {
|
|||
|
||||
class TrickPlayHandlerTest : public MediaHandlerTestBase {
|
||||
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());
|
||||
// Use SetUpGraph to set only input handler, and use
|
||||
// SetHandlerForMainStream and SetHandlerForTrickPlay for the output
|
||||
// handlers.
|
||||
SetUpGraph(1, 0, trick_play_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());
|
||||
}
|
||||
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.
|
||||
TEST_F(TrickPlayHandlerTest, AudioStream) {
|
||||
const std::vector<uint32_t> trick_play_rates(std::begin(kTrickPlayRates),
|
||||
std::end(kTrickPlayRates));
|
||||
SetUpTrickPlayHandler(trick_play_rates);
|
||||
const std::vector<uint32_t> trick_play_factors(std::begin(kTrickPlayFactors),
|
||||
std::end(kTrickPlayFactors));
|
||||
SetUpTrickPlayHandler(trick_play_factors);
|
||||
|
||||
Status status =
|
||||
Process(GetAudioStreamInfoStreamData(kStreamIndex0, kTimeScale));
|
||||
|
@ -97,9 +97,9 @@ TEST_F(TrickPlayHandlerTest, AudioStream) {
|
|||
// This test makes sure the trick play handler can process stream data
|
||||
// correctly.
|
||||
TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
||||
const std::vector<uint32_t> trick_play_rates(std::begin(kTrickPlayRates),
|
||||
std::end(kTrickPlayRates));
|
||||
SetUpTrickPlayHandler(trick_play_rates);
|
||||
const std::vector<uint32_t> trick_play_factors(std::begin(kTrickPlayFactors),
|
||||
std::end(kTrickPlayFactors));
|
||||
SetUpTrickPlayHandler(trick_play_factors);
|
||||
|
||||
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
||||
// The stream info is cached, so the output is empty.
|
||||
|
@ -147,11 +147,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
|||
// Frame 3, key frame.
|
||||
IsKeyFrameMediaSample(
|
||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
||||
// Stream info, TrickPlayRate = 1.
|
||||
// Stream info, TrickPlayFactor = 1.
|
||||
IsTrickPlayVideoStreamInfo(
|
||||
kStreamIndex1, kTimeScale, !kEncrypted, kTrickPlayRates[0],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRates[0]),
|
||||
// Frame 0, TrickPlayRate = 1.
|
||||
kStreamIndex1, kTimeScale, !kEncrypted, kTrickPlayFactors[0],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactors[0]),
|
||||
// Frame 0, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
||||
kDuration * 3),
|
||||
// Frame 4.
|
||||
|
@ -177,15 +177,15 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
|||
// Frame 6, key frame.
|
||||
IsKeyFrameMediaSample(
|
||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
||||
// Frame 3, TrickPlayRate = 1.
|
||||
// Frame 3, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex1,
|
||||
kVideoStartTimestamp + kDuration * 3,
|
||||
kDuration * 3),
|
||||
// Stream info, TrickPlayRate = 2.
|
||||
// Stream info, TrickPlayFactor = 2.
|
||||
IsTrickPlayVideoStreamInfo(
|
||||
kStreamIndex2, kTimeScale, !kEncrypted, kTrickPlayRates[1],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRates[1]),
|
||||
// Frame 0, TrickPlayRate = 2.
|
||||
kStreamIndex2, kTimeScale, !kEncrypted, kTrickPlayFactors[1],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactors[1]),
|
||||
// Frame 0, TrickPlayFactor = 2.
|
||||
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
||||
kDuration * 6),
|
||||
// Frame 7.
|
||||
|
@ -196,11 +196,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
|||
ASSERT_OK(FlushStream(0));
|
||||
EXPECT_THAT(GetOutputStreamDataVector(),
|
||||
ElementsAre(
|
||||
// Frame 6, TrickPlayRate = 1.
|
||||
// Frame 6, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex1,
|
||||
kVideoStartTimestamp + kDuration * 6,
|
||||
kDuration * 2),
|
||||
// Frame 6, TrickPlayRate = 2.
|
||||
// Frame 6, TrickPlayFactor = 2.
|
||||
IsKeyFrameMediaSample(kStreamIndex2,
|
||||
kVideoStartTimestamp + kDuration * 6,
|
||||
kDuration * 2)));
|
||||
|
@ -212,12 +212,12 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithTrickPlay) {
|
|||
}
|
||||
|
||||
// This test makes sure the trick play handler can process stream data
|
||||
// correctly with a decreasing order of trick play rates.
|
||||
TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
||||
const std::vector<uint32_t> trick_play_rates(
|
||||
std::begin(kTrickPlayRatesDecreasing),
|
||||
std::end(kTrickPlayRatesDecreasing));
|
||||
SetUpTrickPlayHandler(trick_play_rates);
|
||||
// correctly with a decreasing order of trick play factors.
|
||||
TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayFactors) {
|
||||
const std::vector<uint32_t> trick_play_factors(
|
||||
std::begin(kTrickPlayFactorsDecreasing),
|
||||
std::end(kTrickPlayFactorsDecreasing));
|
||||
SetUpTrickPlayHandler(trick_play_factors);
|
||||
|
||||
ASSERT_OK(Process(GetVideoStreamInfoStreamData(kStreamIndex0, kTimeScale)));
|
||||
// The stream info is cached, so the output is empty.
|
||||
|
@ -265,12 +265,12 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
|||
// Frame 3, key frame.
|
||||
IsKeyFrameMediaSample(
|
||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 3, kDuration),
|
||||
// Stream info, TrickPlayRate = 1.
|
||||
// Stream info, TrickPlayFactor = 1.
|
||||
IsTrickPlayVideoStreamInfo(
|
||||
kStreamIndex2, kTimeScale, !kEncrypted,
|
||||
kTrickPlayRatesDecreasing[1],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRatesDecreasing[1]),
|
||||
// Frame 0, TrickPlayRate = 1.
|
||||
kTrickPlayFactorsDecreasing[1],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactorsDecreasing[1]),
|
||||
// Frame 0, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex2, kVideoStartTimestamp,
|
||||
kDuration * 3),
|
||||
// Frame 4.
|
||||
|
@ -296,15 +296,15 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
|||
// Frame 6, key frame.
|
||||
IsKeyFrameMediaSample(
|
||||
kStreamIndex0, kVideoStartTimestamp + kDuration * 6, kDuration),
|
||||
// Stream info, TrickPlayRate = 2.
|
||||
// Stream info, TrickPlayFactor = 2.
|
||||
IsTrickPlayVideoStreamInfo(
|
||||
kStreamIndex1, kTimeScale, !kEncrypted,
|
||||
kTrickPlayRatesDecreasing[0],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayRatesDecreasing[0]),
|
||||
// Frame 0, TrickPlayRate = 2.
|
||||
kTrickPlayFactorsDecreasing[0],
|
||||
static_cast<uint32_t>(kGOPSize) * kTrickPlayFactorsDecreasing[0]),
|
||||
// Frame 0, TrickPlayFactor = 2.
|
||||
IsKeyFrameMediaSample(kStreamIndex1, kVideoStartTimestamp,
|
||||
kDuration * 6),
|
||||
// Frame 3, TrickPlayRate = 1.
|
||||
// Frame 3, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex2,
|
||||
kVideoStartTimestamp + kDuration * 3,
|
||||
kDuration * 3),
|
||||
|
@ -316,11 +316,11 @@ TEST_F(TrickPlayHandlerTest, VideoStreamWithDecreasingTrickPlayRates) {
|
|||
ASSERT_OK(FlushStream(0));
|
||||
EXPECT_THAT(GetOutputStreamDataVector(),
|
||||
ElementsAre(
|
||||
// Frame 6, TrickPlayRate = 2.
|
||||
// Frame 6, TrickPlayFactor = 2.
|
||||
IsKeyFrameMediaSample(kStreamIndex1,
|
||||
kVideoStartTimestamp + kDuration * 6,
|
||||
kDuration * 2),
|
||||
// Frame 6, TrickPlayRate = 1.
|
||||
// Frame 6, TrickPlayFactor = 1.
|
||||
IsKeyFrameMediaSample(kStreamIndex2,
|
||||
kVideoStartTimestamp + kDuration * 6,
|
||||
kDuration * 2)));
|
||||
|
|
|
@ -276,7 +276,7 @@ AdaptationSet* DashIopMpdNotifier::NewAdaptationSet(
|
|||
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;
|
||||
if (!FindOriginalAdaptationSetForTrickPlay(media_info,
|
||||
&trick_play_reference_id)) {
|
||||
|
@ -294,7 +294,7 @@ bool DashIopMpdNotifier::FindOriginalAdaptationSetForTrickPlay(
|
|||
const MediaInfo& media_info,
|
||||
uint32_t* main_adaptation_set_id) {
|
||||
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);
|
||||
const std::list<AdaptationSet*>& adaptation_sets =
|
||||
adaptation_set_list_map_[key];
|
||||
|
|
|
@ -167,7 +167,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewContainerForTrickPlay) {
|
|||
" frame_duration: 100\n"
|
||||
" pixel_width: 1\n"
|
||||
" pixel_height: 1\n"
|
||||
" trick_play_rate: 2\n"
|
||||
" trick_play_factor: 2\n"
|
||||
" playback_rate: 10\n"
|
||||
"}\n"
|
||||
"container_type: 1\n";
|
||||
|
|
|
@ -41,9 +41,9 @@ message MediaInfo {
|
|||
optional uint32 pixel_width = 7;
|
||||
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.
|
||||
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
|
||||
// the trick play stream.
|
||||
optional uint32 playback_rate = 10;
|
||||
|
|
|
@ -137,9 +137,9 @@ std::string GetAdaptationSetKey(const MediaInfo& media_info) {
|
|||
key.append(GetLanguage(media_info));
|
||||
|
||||
// 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() &&
|
||||
media_info.video_info().trick_play_rate() > 0) {
|
||||
media_info.video_info().trick_play_factor() > 0) {
|
||||
key.append(":trick_play");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue