Commit b7f65b1f authored by Matt Wolenetz's avatar Matt Wolenetz Committed by Commit Bot

MSE: Remove legacy buffering-by-DTS Part 2: Buffering logic

MseBufferByPts was enabled by default in M75. This series of changes (in M76)
removes:

1) (previous CL) the tests for the old "LegacyByDts" MSE buffering logic, and
2) (this change) the old "LegacyByDts" MSE buffering logic, the
   templating of SourceBufferStream by the buffering implementation, and the
   associated feature gating

Later changes will remove residual complications such as the split
SourceBufferRange and SourceBufferRangeByPts types and clean up
confusing usage of DecodeTimestamp where it really contains a
presentation timestamp within and below FrameProcessor.

BUG=771349,760264,718641,398141

Change-Id: I93491bd47e8cd498b4452f9e5109eb9a7c7b9852
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1586461Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658819}
parent d6d31a18
...@@ -258,10 +258,6 @@ const base::Feature kD3D11VideoDecoderIgnoreWorkarounds{ ...@@ -258,10 +258,6 @@ const base::Feature kD3D11VideoDecoderIgnoreWorkarounds{
const base::Feature kFallbackAfterDecodeError{"FallbackAfterDecodeError", const base::Feature kFallbackAfterDecodeError{"FallbackAfterDecodeError",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
// Manage and report MSE buffered ranges by PTS intervals, not DTS intervals.
const base::Feature kMseBufferByPts{"MseBufferByPts",
base::FEATURE_ENABLED_BY_DEFAULT};
// Enable new cpu load estimator. Intended for evaluation in local // Enable new cpu load estimator. Intended for evaluation in local
// testing and origin-trial. // testing and origin-trial.
// TODO(nisse): Delete once we have switched over to always using the // TODO(nisse): Delete once we have switched over to always using the
......
...@@ -112,7 +112,6 @@ MEDIA_EXPORT extern const base::Feature kMediaCastOverlayButton; ...@@ -112,7 +112,6 @@ MEDIA_EXPORT extern const base::Feature kMediaCastOverlayButton;
MEDIA_EXPORT extern const base::Feature kMediaEngagementBypassAutoplayPolicies; MEDIA_EXPORT extern const base::Feature kMediaEngagementBypassAutoplayPolicies;
MEDIA_EXPORT extern const base::Feature kMediaLearningExperiment; MEDIA_EXPORT extern const base::Feature kMediaLearningExperiment;
MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC; MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC;
MEDIA_EXPORT extern const base::Feature kMseBufferByPts;
MEDIA_EXPORT extern const base::Feature kNewEncodeCpuLoadEstimator; MEDIA_EXPORT extern const base::Feature kNewEncodeCpuLoadEstimator;
MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls; MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls;
MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo;
......
...@@ -391,9 +391,8 @@ MATCHER_P2(NoSpliceForBadMux, overlapped_buffer_count, splice_time_us, "") { ...@@ -391,9 +391,8 @@ MATCHER_P2(NoSpliceForBadMux, overlapped_buffer_count, splice_time_us, "") {
base::NumberToString(splice_time_us)); base::NumberToString(splice_time_us));
} }
MATCHER_P(BufferingByPtsDts, by_pts_bool, "") { MATCHER(ChunkDemuxerCtor, "") {
return CONTAINS_STRING(arg, std::string("ChunkDemuxer: buffering by ") + return CONTAINS_STRING(arg, "ChunkDemuxer");
(by_pts_bool ? "PTS" : "DTS"));
} }
MATCHER_P2(DiscardingEmptyFrame, pts_us, dts_us, "") { MATCHER_P2(DiscardingEmptyFrame, pts_us, dts_us, "") {
......
...@@ -55,8 +55,6 @@ jumbo_source_set("filters") { ...@@ -55,8 +55,6 @@ jumbo_source_set("filters") {
"source_buffer_parse_warnings.h", "source_buffer_parse_warnings.h",
"source_buffer_range.cc", "source_buffer_range.cc",
"source_buffer_range.h", "source_buffer_range.h",
"source_buffer_range_by_dts.cc",
"source_buffer_range_by_dts.h",
"source_buffer_range_by_pts.cc", "source_buffer_range_by_pts.cc",
"source_buffer_range_by_pts.h", "source_buffer_range_by_pts.h",
"source_buffer_state.cc", "source_buffer_state.cc",
......
This diff is collapsed.
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#include "media/base/ranges.h" #include "media/base/ranges.h"
#include "media/base/stream_parser.h" #include "media/base/stream_parser.h"
#include "media/filters/source_buffer_parse_warnings.h" #include "media/filters/source_buffer_parse_warnings.h"
#include "media/filters/source_buffer_range_by_dts.h"
#include "media/filters/source_buffer_range_by_pts.h"
#include "media/filters/source_buffer_state.h" #include "media/filters/source_buffer_state.h"
#include "media/filters/source_buffer_stream.h" #include "media/filters/source_buffer_stream.h"
...@@ -35,25 +33,11 @@ class MEDIA_EXPORT SourceBufferStream; ...@@ -35,25 +33,11 @@ class MEDIA_EXPORT SourceBufferStream;
namespace media { namespace media {
template <>
void SourceBufferStream<SourceBufferRangeByPts>::OnStartOfCodedFrameGroup(
DecodeTimestamp coded_frame_group_start_dts,
base::TimeDelta coded_frame_group_start_pts);
template <>
void SourceBufferStream<SourceBufferRangeByDts>::OnStartOfCodedFrameGroup(
DecodeTimestamp coded_frame_group_start_dts,
base::TimeDelta coded_frame_group_start_pts);
class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream { class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream {
public: public:
using BufferQueue = base::circular_deque<scoped_refptr<StreamParserBuffer>>; using BufferQueue = base::circular_deque<scoped_refptr<StreamParserBuffer>>;
enum class RangeApi { kLegacyByDts, kNewByPts }; ChunkDemuxerStream(Type type, MediaTrack::Id media_track_id);
ChunkDemuxerStream(Type type,
MediaTrack::Id media_track_id,
RangeApi range_api);
~ChunkDemuxerStream() override; ~ChunkDemuxerStream() override;
// ChunkDemuxerStream control methods. // ChunkDemuxerStream control methods.
...@@ -182,16 +166,10 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream { ...@@ -182,16 +166,10 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream {
// Specifies the type of the stream. // Specifies the type of the stream.
const Type type_; const Type type_;
const RangeApi range_api_;
Liveness liveness_ GUARDED_BY(lock_); Liveness liveness_ GUARDED_BY(lock_);
// Precisely one of these will be used by an instance, determined by std::unique_ptr<SourceBufferStream> stream_ GUARDED_BY(lock_);
// |range_api_| set in ctor. See https://crbug.com/718641.
std::unique_ptr<SourceBufferStream<SourceBufferRangeByDts>> stream_dts_
GUARDED_BY(lock_);
std::unique_ptr<SourceBufferStream<SourceBufferRangeByPts>> stream_pts_
GUARDED_BY(lock_);
const MediaTrack::Id media_track_id_; const MediaTrack::Id media_track_id_;
...@@ -545,11 +523,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { ...@@ -545,11 +523,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
int detected_video_track_count_; int detected_video_track_count_;
int detected_text_track_count_; int detected_text_track_count_;
// Caches whether |media::kMseBufferByPts| feature was enabled at ChunkDemuxer
// construction time. This makes sure that all buffering for this ChunkDemuxer
// uses the same behavior. See https://crbug.com/718641.
const bool buffering_by_pts_;
// Callback for reporting the number of bytes appended to this ChunkDemuxer. // Callback for reporting the number of bytes appended to this ChunkDemuxer.
BytesReceivedCB bytes_received_cb_; BytesReceivedCB bytes_received_cb_;
......
...@@ -190,7 +190,7 @@ class ChunkDemuxerTest : public ::testing::Test { ...@@ -190,7 +190,7 @@ class ChunkDemuxerTest : public ::testing::Test {
Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
base::BindRepeating(&ChunkDemuxerTest::OnEncryptedMediaInitData, base::BindRepeating(&ChunkDemuxerTest::OnEncryptedMediaInitData,
base::Unretained(this)); base::Unretained(this));
EXPECT_MEDIA_LOG(BufferingByPtsDts(true)); EXPECT_MEDIA_LOG(ChunkDemuxerCtor());
demuxer_.reset(new ChunkDemuxer(open_cb, progress_cb, demuxer_.reset(new ChunkDemuxer(open_cb, progress_cb,
encrypted_media_init_data_cb, &media_log_)); encrypted_media_init_data_cb, &media_log_));
} }
......
...@@ -32,8 +32,7 @@ class MseTrackBuffer { ...@@ -32,8 +32,7 @@ class MseTrackBuffer {
public: public:
MseTrackBuffer(ChunkDemuxerStream* stream, MseTrackBuffer(ChunkDemuxerStream* stream,
MediaLog* media_log, MediaLog* media_log,
const SourceBufferParseWarningCB& parse_warning_cb, const SourceBufferParseWarningCB& parse_warning_cb);
ChunkDemuxerStream::RangeApi range_api);
~MseTrackBuffer(); ~MseTrackBuffer();
// Get/set |last_decode_timestamp_|. // Get/set |last_decode_timestamp_|.
...@@ -154,7 +153,6 @@ class MseTrackBuffer { ...@@ -154,7 +153,6 @@ class MseTrackBuffer {
// EnqueueProcessedFrame(). // EnqueueProcessedFrame().
base::TimeDelta last_signalled_group_start_pts_; base::TimeDelta last_signalled_group_start_pts_;
bool have_flushed_since_last_group_start_; bool have_flushed_since_last_group_start_;
ChunkDemuxerStream::RangeApi range_api_;
// The coded frame duration of the last coded frame appended in the current // The coded frame duration of the last coded frame appended in the current
// coded frame group. Initially kNoTimestamp, meaning "unset". // coded frame group. Initially kNoTimestamp, meaning "unset".
...@@ -196,15 +194,13 @@ class MseTrackBuffer { ...@@ -196,15 +194,13 @@ class MseTrackBuffer {
MseTrackBuffer::MseTrackBuffer( MseTrackBuffer::MseTrackBuffer(
ChunkDemuxerStream* stream, ChunkDemuxerStream* stream,
MediaLog* media_log, MediaLog* media_log,
const SourceBufferParseWarningCB& parse_warning_cb, const SourceBufferParseWarningCB& parse_warning_cb)
ChunkDemuxerStream::RangeApi range_api)
: last_decode_timestamp_(kNoDecodeTimestamp()), : last_decode_timestamp_(kNoDecodeTimestamp()),
last_processed_decode_timestamp_(DecodeTimestamp()), last_processed_decode_timestamp_(DecodeTimestamp()),
pending_group_start_pts_(kNoTimestamp), pending_group_start_pts_(kNoTimestamp),
last_keyframe_presentation_timestamp_(kNoTimestamp), last_keyframe_presentation_timestamp_(kNoTimestamp),
last_signalled_group_start_pts_(kNoTimestamp), last_signalled_group_start_pts_(kNoTimestamp),
have_flushed_since_last_group_start_(false), have_flushed_since_last_group_start_(false),
range_api_(range_api),
last_frame_duration_(kNoTimestamp), last_frame_duration_(kNoTimestamp),
highest_presentation_timestamp_(kNoTimestamp), highest_presentation_timestamp_(kNoTimestamp),
needs_random_access_point_(true), needs_random_access_point_(true),
...@@ -276,17 +272,16 @@ bool MseTrackBuffer::EnqueueProcessedFrame( ...@@ -276,17 +272,16 @@ bool MseTrackBuffer::EnqueueProcessedFrame(
"well supported by MSE; buffered range reporting may be less " "well supported by MSE; buffered range reporting may be less "
"precise."; "precise.";
// SAP-Type-2 GOPs (when buffering ByPts), by definition, contain at // SAP-Type-2 GOPs, by definition, contain at least one non-keyframe with
// least one non-keyframe with PTS prior to the keyframe's PTS, with DTS // PTS prior to the keyframe's PTS, with DTS continuous from keyframe
// continuous from keyframe forward to at least that non-keyframe. If // forward to at least that non-keyframe. If such a non-keyframe overlaps
// such a non-keyframe overlaps the end of a previously buffered GOP // the end of a previously buffered GOP sufficiently (such that, say, some
// sufficiently (such that, say, some previous GOP's non-keyframes // previous GOP's non-keyframes depending on the overlapped
// depending on the overlapped non-keyframe(s) must be dropped), then a // non-keyframe(s) must be dropped), then a gap might need to result. But
// gap might need to result. But if we attempt to buffer the new GOP's // if we attempt to buffer the new GOP's keyframe through at least that
// keyframe through at least that first non-keyframe that does such // first non-keyframe that does such overlapping all at once, the
// overlapping all at once, the buffering mechanism doesn't expect such // buffering mechanism doesn't expect such a discontinuity could occur
// a discontinuity could occur (failing assumptions in places like // (failing assumptions in places like SourceBufferRange).
// SourceBufferRangeByPts).
// //
// To prevent such failure, we can first flush what's previously been // To prevent such failure, we can first flush what's previously been
// enqueued (if anything), but do this conservatively to not flush // enqueued (if anything), but do this conservatively to not flush
...@@ -295,8 +290,7 @@ bool MseTrackBuffer::EnqueueProcessedFrame( ...@@ -295,8 +290,7 @@ bool MseTrackBuffer::EnqueueProcessedFrame(
// this track and no flush has yet occurred for this track since then, or // this track and no flush has yet occurred for this track since then, or
// if there has been a flush since then but this nonkeyframe's PTS is no // if there has been a flush since then but this nonkeyframe's PTS is no
// lower than the PTS of the first frame pending flush currently. // lower than the PTS of the first frame pending flush currently.
if (range_api_ == ChunkDemuxerStream::RangeApi::kNewByPts && if (!processed_frames_.empty()) {
!processed_frames_.empty()) {
DCHECK(kNoTimestamp != last_signalled_group_start_pts_); DCHECK(kNoTimestamp != last_signalled_group_start_pts_);
if (!have_flushed_since_last_group_start_) { if (!have_flushed_since_last_group_start_) {
...@@ -347,12 +341,10 @@ void MseTrackBuffer::NotifyStartOfCodedFrameGroup(DecodeTimestamp start_dts, ...@@ -347,12 +341,10 @@ void MseTrackBuffer::NotifyStartOfCodedFrameGroup(DecodeTimestamp start_dts,
} }
FrameProcessor::FrameProcessor(const UpdateDurationCB& update_duration_cb, FrameProcessor::FrameProcessor(const UpdateDurationCB& update_duration_cb,
MediaLog* media_log, MediaLog* media_log)
ChunkDemuxerStream::RangeApi range_api)
: group_start_timestamp_(kNoTimestamp), : group_start_timestamp_(kNoTimestamp),
update_duration_cb_(update_duration_cb), update_duration_cb_(update_duration_cb),
media_log_(media_log), media_log_(media_log) {
range_api_(range_api) {
DVLOG(2) << __func__ << "()"; DVLOG(2) << __func__ << "()";
DCHECK(update_duration_cb); DCHECK(update_duration_cb);
} }
...@@ -486,8 +478,8 @@ bool FrameProcessor::AddTrack(StreamParser::TrackId id, ...@@ -486,8 +478,8 @@ bool FrameProcessor::AddTrack(StreamParser::TrackId id,
return false; return false;
} }
track_buffers_[id] = std::make_unique<MseTrackBuffer>( track_buffers_[id] =
stream, media_log_, parse_warning_cb_, range_api_); std::make_unique<MseTrackBuffer>(stream, media_log_, parse_warning_cb_);
return true; return true;
} }
...@@ -927,22 +919,6 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame, ...@@ -927,22 +919,6 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame,
} }
DCHECK(presentation_timestamp >= base::TimeDelta()); DCHECK(presentation_timestamp >= base::TimeDelta());
if (decode_timestamp < DecodeTimestamp() &&
range_api_ == ChunkDemuxerStream::RangeApi::kLegacyByDts) {
// B-frames may still result in negative DTS here after being shifted by
// |timestamp_offset_|.
// TODO(wolenetz): This is no longer a step in the CFP, since negative DTS
// are allowed. Remove this parse failure and error log as part of fixing
// PTS/DTS conflation in SourceBufferStream. See https://crbug.com/398141
// and https://crbug.com/718641.
MEDIA_LOG(ERROR, media_log_)
<< frame->GetTypeName() << " frame with PTS "
<< presentation_timestamp.InMicroseconds() << "us has negative DTS "
<< decode_timestamp.InMicroseconds()
<< "us after applying timestampOffset, handling any discontinuity, "
"and filtering against append window";
return false;
}
// 10. If the need random access point flag on track buffer equals true, // 10. If the need random access point flag on track buffer equals true,
// then run the following steps: // then run the following steps:
...@@ -985,13 +961,11 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame, ...@@ -985,13 +961,11 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame,
(track_buffer->pending_group_start_pts() != kNoTimestamp && (track_buffer->pending_group_start_pts() != kNoTimestamp &&
track_buffer->pending_group_start_pts() > presentation_timestamp); track_buffer->pending_group_start_pts() > presentation_timestamp);
if (range_api_ == ChunkDemuxerStream::RangeApi::kNewByPts && if (frame->is_key_frame()) {
frame->is_key_frame()) { // When a keyframe is discovered to have a decreasing PTS versus the
// When buffering by PTS intervals and a keyframe is discovered to have a // previous highest presentation timestamp for that track in the current
// decreasing PTS versus the previous highest presentation timestamp for // coded frame group, signal a new coded frame group for that track buffer
// that track in the current coded frame group, signal a new coded frame // so that it can correctly process overlap-removals for the new GOP.
// group for that track buffer so that it can correctly process
// overlap-removals for the new GOP.
if (track_buffer->highest_presentation_timestamp() != kNoTimestamp && if (track_buffer->highest_presentation_timestamp() != kNoTimestamp &&
track_buffer->highest_presentation_timestamp() > track_buffer->highest_presentation_timestamp() >
presentation_timestamp) { presentation_timestamp) {
...@@ -1004,13 +978,13 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame, ...@@ -1004,13 +978,13 @@ bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame,
track_buffer->ResetHighestPresentationTimestamp(); track_buffer->ResetHighestPresentationTimestamp();
} }
// When buffering by PTS intervals and an otherwise continuous coded frame // When an otherwise continuous coded frame group (by DTS, and with
// group (by DTS, and with non-decreasing keyframe PTS) contains a // non-decreasing keyframe PTS) contains a keyframe with PTS in the future
// keyframe with PTS in the future significantly far enough that it may be // significantly far enough that it may be outside of buffering fudge
// outside of buffering fudge room, signal a new coded frame group with // room, signal a new coded frame group with start time set to the
// start time set to the previous highest frame end time in the coded // previous highest frame end time in the coded frame group for this
// frame group for this track. This lets the stream coalesce a potential // track. This lets the stream coalesce a potential gap, and also pass
// gap, and also pass internal buffer adjacency checks. // internal buffer adjacency checks.
signal_new_cfg |= signal_new_cfg |=
track_buffer->highest_presentation_timestamp() != kNoTimestamp && track_buffer->highest_presentation_timestamp() != kNoTimestamp &&
track_buffer->highest_presentation_timestamp() + frame->duration() < track_buffer->highest_presentation_timestamp() + frame->duration() <
......
...@@ -28,8 +28,7 @@ class MEDIA_EXPORT FrameProcessor { ...@@ -28,8 +28,7 @@ class MEDIA_EXPORT FrameProcessor {
typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB; typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB;
FrameProcessor(const UpdateDurationCB& update_duration_cb, FrameProcessor(const UpdateDurationCB& update_duration_cb,
MediaLog* media_log, MediaLog* media_log);
ChunkDemuxerStream::RangeApi range_api);
~FrameProcessor(); ~FrameProcessor();
// This must be called exactly once, before doing any track buffer creation or // This must be called exactly once, before doing any track buffer creation or
...@@ -177,10 +176,6 @@ class MEDIA_EXPORT FrameProcessor { ...@@ -177,10 +176,6 @@ class MEDIA_EXPORT FrameProcessor {
// MediaLog for reporting messages and properties to debug content and engine. // MediaLog for reporting messages and properties to debug content and engine.
MediaLog* media_log_; MediaLog* media_log_;
// For differentiating behavior based on buffering by DTS interval versus PTS
// interval. See https://crbug.com/718641.
const ChunkDemuxerStream::RangeApi range_api_;
// Callback for reporting problematic conditions that are not necessarily // Callback for reporting problematic conditions that are not necessarily
// errors. // errors.
SourceBufferParseWarningCB parse_warning_cb_; SourceBufferParseWarningCB parse_warning_cb_;
......
...@@ -86,16 +86,11 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> { ...@@ -86,16 +86,11 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> {
audio_id_(1), audio_id_(1),
video_id_(2) { video_id_(2) {
use_sequence_mode_ = GetParam(); use_sequence_mode_ = GetParam();
// TODO(wolenetz): Remove range API parameterization once production code no
// longer varies per kMseBufferByPts feature. See https://crbug.com/771349
range_api_ = ChunkDemuxerStream::RangeApi::kNewByPts;
frame_processor_ = std::make_unique<FrameProcessor>( frame_processor_ = std::make_unique<FrameProcessor>(
base::Bind( base::Bind(
&FrameProcessorTestCallbackHelper::OnPossibleDurationIncrease, &FrameProcessorTestCallbackHelper::OnPossibleDurationIncrease,
base::Unretained(&callbacks_)), base::Unretained(&callbacks_)),
&media_log_, range_api_); &media_log_);
frame_processor_->SetParseWarningCallback( frame_processor_->SetParseWarningCallback(
base::Bind(&FrameProcessorTestCallbackHelper::OnParseWarning, base::Bind(&FrameProcessorTestCallbackHelper::OnParseWarning,
base::Unretained(&callbacks_))); base::Unretained(&callbacks_)));
...@@ -308,7 +303,6 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> { ...@@ -308,7 +303,6 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> {
StrictMock<FrameProcessorTestCallbackHelper> callbacks_; StrictMock<FrameProcessorTestCallbackHelper> callbacks_;
bool use_sequence_mode_; bool use_sequence_mode_;
ChunkDemuxerStream::RangeApi range_api_;
std::unique_ptr<FrameProcessor> frame_processor_; std::unique_ptr<FrameProcessor> frame_processor_;
base::TimeDelta append_window_start_; base::TimeDelta append_window_start_;
...@@ -349,8 +343,7 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> { ...@@ -349,8 +343,7 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> {
switch (type) { switch (type) {
case DemuxerStream::AUDIO: { case DemuxerStream::AUDIO: {
ASSERT_FALSE(audio_); ASSERT_FALSE(audio_);
audio_.reset( audio_.reset(new ChunkDemuxerStream(DemuxerStream::AUDIO, "1"));
new ChunkDemuxerStream(DemuxerStream::AUDIO, "1", range_api_));
AudioDecoderConfig decoder_config(kCodecVorbis, kSampleFormatPlanarF32, AudioDecoderConfig decoder_config(kCodecVorbis, kSampleFormatPlanarF32,
CHANNEL_LAYOUT_STEREO, 1000, CHANNEL_LAYOUT_STEREO, 1000,
EmptyExtraData(), Unencrypted()); EmptyExtraData(), Unencrypted());
...@@ -363,8 +356,7 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> { ...@@ -363,8 +356,7 @@ class FrameProcessorTest : public ::testing::TestWithParam<bool> {
} }
case DemuxerStream::VIDEO: { case DemuxerStream::VIDEO: {
ASSERT_FALSE(video_); ASSERT_FALSE(video_);
video_.reset( video_.reset(new ChunkDemuxerStream(DemuxerStream::VIDEO, "2"));
new ChunkDemuxerStream(DemuxerStream::VIDEO, "2", range_api_));
ASSERT_TRUE(video_->UpdateVideoConfig(TestVideoConfig::Normal(), false, ASSERT_TRUE(video_->UpdateVideoConfig(TestVideoConfig::Normal(), false,
&media_log_)); &media_log_));
stream = video_.get(); stream = video_.get();
...@@ -1248,8 +1240,7 @@ TEST_P(FrameProcessorTest, TimestampOffsetNegativeDts) { ...@@ -1248,8 +1240,7 @@ TEST_P(FrameProcessorTest, TimestampOffsetNegativeDts) {
TEST_P(FrameProcessorTest, LargeTimestampOffsetJumpForward) { TEST_P(FrameProcessorTest, LargeTimestampOffsetJumpForward) {
// Verifies that jumps forward in buffers emitted from the coded frame // Verifies that jumps forward in buffers emitted from the coded frame
// processing algorithm can create discontinuous buffered ranges if those // processing algorithm can create discontinuous buffered ranges if those
// jumps are large enough, in both kinds of AppendMode, and in both kinds of // jumps are large enough, in both kinds of AppendMode.
// RangeApi.
InSequence s; InSequence s;
AddTestTracks(HAS_AUDIO); AddTestTracks(HAS_AUDIO);
frame_processor_->SetSequenceMode(use_sequence_mode_); frame_processor_->SetSequenceMode(use_sequence_mode_);
......
...@@ -88,7 +88,7 @@ class MEDIA_EXPORT SourceBufferRange { ...@@ -88,7 +88,7 @@ class MEDIA_EXPORT SourceBufferRange {
// TODO(wolenetz): Remove in favor of // TODO(wolenetz): Remove in favor of
// GetEndTimestamp()/GetBufferedEndTimestamp() once they report in PTS, not // GetEndTimestamp()/GetBufferedEndTimestamp() once they report in PTS, not
// DTS. See https://crbug.com/718641. // DTS. See https://crbug.com/771349.
void GetRangeEndTimesForTesting(base::TimeDelta* highest_pts, void GetRangeEndTimesForTesting(base::TimeDelta* highest_pts,
base::TimeDelta* end_time) const; base::TimeDelta* end_time) const;
...@@ -109,7 +109,7 @@ class MEDIA_EXPORT SourceBufferRange { ...@@ -109,7 +109,7 @@ class MEDIA_EXPORT SourceBufferRange {
// updates the |size_in_bytes_| accordingly. Note, this does not update // updates the |size_in_bytes_| accordingly. Note, this does not update
// |keyframe_map_|. // |keyframe_map_|.
// TODO(wolenetz): elevate keyframe_map_ to base class so this comment has // TODO(wolenetz): elevate keyframe_map_ to base class so this comment has
// better context. See https://crbug.com/718641. // better context. See https://crbug.com/771349.
void FreeBufferRange(const BufferQueue::const_iterator& starting_point, void FreeBufferRange(const BufferQueue::const_iterator& starting_point,
const BufferQueue::const_iterator& ending_point); const BufferQueue::const_iterator& ending_point);
...@@ -128,10 +128,7 @@ class MEDIA_EXPORT SourceBufferRange { ...@@ -128,10 +128,7 @@ class MEDIA_EXPORT SourceBufferRange {
// the next buffer in presentation sequence at or after |highest_frame_|. // the next buffer in presentation sequence at or after |highest_frame_|.
// |buffers_| must not be empty, and |highest_frame_| must not be nullptr. // |buffers_| must not be empty, and |highest_frame_| must not be nullptr.
// Uses |gap_policy_| to potentially allow gaps. // Uses |gap_policy_| to potentially allow gaps.
// TODO(wolenetz): Switch to using this helper in CanAppendBuffersToEnd(), //
// etc, when switching to managing ranges by their presentation interval, and
// not necessarily just their decode times. See https://crbug.com/718641. Once
// being used and not just tested, the following also applies:
// Due to potential for out-of-order decode vs presentation time, this method // Due to potential for out-of-order decode vs presentation time, this method
// should only be used to determine adjacency of keyframes with the end of // should only be used to determine adjacency of keyframes with the end of
// |buffers_|. // |buffers_|.
...@@ -141,10 +138,7 @@ class MEDIA_EXPORT SourceBufferRange { ...@@ -141,10 +138,7 @@ class MEDIA_EXPORT SourceBufferRange {
// timestamp of the next buffer in decode sequence at or after the last buffer // timestamp of the next buffer in decode sequence at or after the last buffer
// in |buffers_|'s decode timestamp. |buffers_| must not be empty. Uses // in |buffers_|'s decode timestamp. |buffers_| must not be empty. Uses
// |gap_policy_| to potentially allow gaps. // |gap_policy_| to potentially allow gaps.
// TODO(wolenetz): Switch to using this helper in CanAppendBuffersToEnd(), //
// etc, appropriately when switching to managing ranges by their presentation
// interval between GOPs, and by their decode sequence within GOPs. See
// https://crbug.com/718641. Once that's done, the following also would apply:
// Due to potential for out-of-order decode vs presentation time, this method // Due to potential for out-of-order decode vs presentation time, this method
// should only be used to determine adjacency of non-keyframes with the end of // should only be used to determine adjacency of non-keyframes with the end of
// |buffers_|, when determining if a non-keyframe with |decode_timestamp| // |buffers_|, when determining if a non-keyframe with |decode_timestamp|
......
This diff is collapsed.
This diff is collapsed.
...@@ -112,13 +112,6 @@ void SourceBufferRangeByPts::AppendBuffersToEnd( ...@@ -112,13 +112,6 @@ void SourceBufferRangeByPts::AppendBuffersToEnd(
new_buffers.front()->is_key_frame()) new_buffers.front()->is_key_frame())
<< range_start_pts_ << ", " << new_buffers.front()->is_key_frame(); << range_start_pts_ << ", " << new_buffers.front()->is_key_frame();
// TODO(wolenetz): Uncomment this DCHECK once SAP-Type-2 is more fully
// supported. It is hit by NewByPts versions of
// FrameProcessorTest.OOOKeyframePrecededByDependantNonKeyframeShouldWarn. See
// https://crbug.com/718641.
// DCHECK(range_start_pts_ == kNoTimestamp ||
// range_start_pts_ <= new_buffers.front()->timestamp());
AdjustEstimatedDurationForNewAppend(new_buffers); AdjustEstimatedDurationForNewAppend(new_buffers);
for (BufferQueue::const_iterator itr = new_buffers.begin(); for (BufferQueue::const_iterator itr = new_buffers.begin();
......
...@@ -56,17 +56,13 @@ void InvokeCbAndSaveResult(const base::Callback<bool()>& cb, bool* result) { ...@@ -56,17 +56,13 @@ void InvokeCbAndSaveResult(const base::Callback<bool()>& cb, bool* result) {
class SourceBufferStateTest : public ::testing::Test { class SourceBufferStateTest : public ::testing::Test {
public: public:
SourceBufferStateTest() : mock_stream_parser_(nullptr) { SourceBufferStateTest() : mock_stream_parser_(nullptr) {}
// TODO(wolenetz): Remove range API parameterization once production code no
// longer varies per kMseBufferByPts feature. See https://crbug.com/771349.
range_api_ = ChunkDemuxerStream::RangeApi::kNewByPts;
}
std::unique_ptr<SourceBufferState> CreateSourceBufferState() { std::unique_ptr<SourceBufferState> CreateSourceBufferState() {
std::unique_ptr<FrameProcessor> frame_processor = base::WrapUnique( std::unique_ptr<FrameProcessor> frame_processor = base::WrapUnique(
new FrameProcessor(base::Bind(&SourceBufferStateTest::OnUpdateDuration, new FrameProcessor(base::Bind(&SourceBufferStateTest::OnUpdateDuration,
base::Unretained(this)), base::Unretained(this)),
&media_log_, range_api_)); &media_log_));
mock_stream_parser_ = new testing::StrictMock<MockStreamParser>(); mock_stream_parser_ = new testing::StrictMock<MockStreamParser>();
return base::WrapUnique(new SourceBufferState( return base::WrapUnique(new SourceBufferState(
base::WrapUnique(mock_stream_parser_), std::move(frame_processor), base::WrapUnique(mock_stream_parser_), std::move(frame_processor),
...@@ -145,8 +141,8 @@ class SourceBufferStateTest : public ::testing::Test { ...@@ -145,8 +141,8 @@ class SourceBufferStateTest : public ::testing::Test {
ChunkDemuxerStream* CreateDemuxerStream(DemuxerStream::Type type) { ChunkDemuxerStream* CreateDemuxerStream(DemuxerStream::Type type) {
static unsigned track_id = 0; static unsigned track_id = 0;
demuxer_streams_.push_back(base::WrapUnique(new ChunkDemuxerStream( demuxer_streams_.push_back(base::WrapUnique(
type, base::NumberToString(++track_id), range_api_))); new ChunkDemuxerStream(type, base::NumberToString(++track_id))));
return demuxer_streams_.back().get(); return demuxer_streams_.back().get();
} }
...@@ -154,7 +150,6 @@ class SourceBufferStateTest : public ::testing::Test { ...@@ -154,7 +150,6 @@ class SourceBufferStateTest : public ::testing::Test {
std::vector<std::unique_ptr<ChunkDemuxerStream>> demuxer_streams_; std::vector<std::unique_ptr<ChunkDemuxerStream>> demuxer_streams_;
MockStreamParser* mock_stream_parser_; MockStreamParser* mock_stream_parser_;
StreamParser::NewConfigCB new_config_cb_; StreamParser::NewConfigCB new_config_cb_;
ChunkDemuxerStream::RangeApi range_api_;
}; };
TEST_F(SourceBufferStateTest, InitSingleAudioTrack) { TEST_F(SourceBufferStateTest, InitSingleAudioTrack) {
......
This diff is collapsed.
This diff is collapsed.
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "media/base/timestamp_constants.h" #include "media/base/timestamp_constants.h"
#include "media/base/webvtt_util.h" #include "media/base/webvtt_util.h"
#include "media/filters/source_buffer_range.h" #include "media/filters/source_buffer_range.h"
#include "media/filters/source_buffer_range_by_dts.h"
#include "media/filters/source_buffer_range_by_pts.h" #include "media/filters/source_buffer_range_by_pts.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -83,8 +82,7 @@ class SourceBufferStreamTest : public testing::Test { ...@@ -83,8 +82,7 @@ class SourceBufferStreamTest : public testing::Test {
template <typename ConfigT> template <typename ConfigT>
void ResetStream(const ConfigT& config) { void ResetStream(const ConfigT& config) {
stream_.reset( stream_.reset(new SourceBufferStream(config, &media_log_));
new SourceBufferStream<SourceBufferRangeByPts>(config, &media_log_));
} }
void SetMemoryLimit(size_t buffers_of_data) { void SetMemoryLimit(size_t buffers_of_data) {
...@@ -458,7 +456,7 @@ class SourceBufferStreamTest : public testing::Test { ...@@ -458,7 +456,7 @@ class SourceBufferStreamTest : public testing::Test {
base::TimeDelta frame_duration() const { return frame_duration_; } base::TimeDelta frame_duration() const { return frame_duration_; }
StrictMock<MockMediaLog> media_log_; StrictMock<MockMediaLog> media_log_;
std::unique_ptr<SourceBufferStream<SourceBufferRangeByPts>> stream_; std::unique_ptr<SourceBufferStream> stream_;
VideoDecoderConfig video_config_; VideoDecoderConfig video_config_;
AudioDecoderConfig audio_config_; AudioDecoderConfig audio_config_;
...@@ -894,11 +892,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Several) { ...@@ -894,11 +892,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Several) {
// Check expected ranges: stream should not have kept buffers at DTS 13,14; // Check expected ranges: stream should not have kept buffers at DTS 13,14;
// PTS 12,13 because the keyframe on which they depended (10, PTS=DTS) was // PTS 12,13 because the keyframe on which they depended (10, PTS=DTS) was
// overwritten. Note that partial second GOP of B includes PTS [10,14), DTS // overwritten. Note that partial second GOP of B includes PTS [10,14), DTS
// [10,12). In both ByDts and ByPts, these are continuous with the overlapped // [10,12). These are continuous with the overlapped original range's next GOP
// original range's next GOP at (15, PTS=DTS). // at (15, PTS=DTS).
// Unlike the rest of the position based test API used in this case, these // Unlike the rest of the position based test API used in this case, these
// range expectation strings are the actual timestamps (divided by // range expectation strings are the actual timestamps (divided by
// frame_duration_), in DTS if ByDts, in PTS if ByPts. // frame_duration_).
CheckExpectedRanges("{ [5,19) }"); CheckExpectedRanges("{ [5,19) }");
// Check buffers in range. // Check buffers in range.
...@@ -1279,11 +1277,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_AfterEndOfNew_2) { ...@@ -1279,11 +1277,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_AfterEndOfNew_2) {
// Check expected ranges: stream should not have kept buffers at DTS 8,9; // Check expected ranges: stream should not have kept buffers at DTS 8,9;
// PTS 7,8 because the keyframe on which they depended (5, PTS=DTS) was // PTS 7,8 because the keyframe on which they depended (5, PTS=DTS) was
// overwritten. Note that partial second GOP of B includes PTS [5,9), DTS // overwritten. Note that partial second GOP of B includes PTS [5,9), DTS
// [5,7). In both ByDts and ByPts, these are continuous with the overlapped // [5,7). These are continuous with the overlapped original range's next GOP
// original range's next GOP at (10, PTS=DTS). // at (10, PTS=DTS).
// Unlike the rest of the position based test API used in this case, these // Unlike the rest of the position based test API used in this case, these
// range expectation strings are the actual timestamps (divided by // range expectation strings are the actual timestamps (divided by
// frame_duration_), in DTS if ByDts, in PTS if ByPts. // frame_duration_).
CheckExpectedRanges("{ [0,14) }"); CheckExpectedRanges("{ [0,14) }");
// Make sure rest of data is as expected. // Make sure rest of data is as expected.
...@@ -1323,11 +1321,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_AfterEndOfNew_3) { ...@@ -1323,11 +1321,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_AfterEndOfNew_3) {
// PTS 7,8 because the keyframe on which they depended (5, PTS=DTS) was // PTS 7,8 because the keyframe on which they depended (5, PTS=DTS) was
// overwritten. However, they were in the GOP being read from, so were put // overwritten. However, they were in the GOP being read from, so were put
// into the track buffer. Note that partial second GOP of B includes PTS // into the track buffer. Note that partial second GOP of B includes PTS
// [5,9), DTS [5,7). In both ByDts and ByPts, these are continuous with the // [5,9), DTS [5,7). These are continuous with the overlapped original range's
// overlapped original range's next GOP at (10, PTS=DTS). // next GOP at (10, PTS=DTS).
// Unlike the rest of the position based test API used in this case, these // Unlike the rest of the position based test API used in this case, these
// range expectation strings are the actual timestamps (divided by // range expectation strings are the actual timestamps (divided by
// frame_duration_), in DTS if ByDts, in PTS if ByPts. // frame_duration_).
CheckExpectedRanges("{ [0,14) }"); CheckExpectedRanges("{ [0,14) }");
// Check for data in the track buffer. // Check for data in the track buffer.
...@@ -1402,11 +1400,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_OverlappedByNew_2) { ...@@ -1402,11 +1400,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_OverlappedByNew_2) {
// PTS 6,7,8 because the keyframe on which they depended (5, PTS=DTS) was // PTS 6,7,8 because the keyframe on which they depended (5, PTS=DTS) was
// overwritten. However, they were in the GOP being read from, so were put // overwritten. However, they were in the GOP being read from, so were put
// into the track buffer. Note that partial second GOP of B includes PTS // into the track buffer. Note that partial second GOP of B includes PTS
// [5,9), DTS [5,6). In both ByDts and ByPts, these are continuous with the // [5,9), DTS [5,6). These are continuous with the overlapped original range's
// overlapped original range's next GOP at (10, PTS=DTS). // next GOP at (10, PTS=DTS).
// Unlike the rest of the position based test API used in this case, these // Unlike the rest of the position based test API used in this case, these
// range expectation strings are the actual timestamps (divided by // range expectation strings are the actual timestamps (divided by
// frame_duration_), in DTS if ByDts, in PTS if ByPts. // frame_duration_).
CheckExpectedRanges("{ [0,14) }"); CheckExpectedRanges("{ [0,14) }");
// Check for data in the track buffer. // Check for data in the track buffer.
...@@ -1450,11 +1448,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_OverlappedByNew_3) { ...@@ -1450,11 +1448,11 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_OverlappedByNew_3) {
// and PTS) because the keyframe on which they depended (10, PTS=DTS) was // and PTS) because the keyframe on which they depended (10, PTS=DTS) was
// overwritten. The GOP being read from was overwritten, so track buffer // overwritten. The GOP being read from was overwritten, so track buffer
// should contain DTS 6-9 (PTS 9,6,7,8). Note that the partial third GOP of B // should contain DTS 6-9 (PTS 9,6,7,8). Note that the partial third GOP of B
// includes (10, PTS=DTS). In both ByDts and ByPts, this partial GOP is // includes (10, PTS=DTS). This partial GOP is continuous with the overlapped
// continuous with the overlapped original range's next GOP at (15, PTS=DTS). // original range's next GOP at (15, PTS=DTS).
// Unlike the rest of the position based test API used in this case, these // Unlike the rest of the position based test API used in this case, these
// range expectation strings are the actual timestamps (divided by // range expectation strings are the actual timestamps (divided by
// frame_duration_), in DTS if ByDts, in PTS if ByPts. // frame_duration_).
CheckExpectedRanges("{ [0,19) }"); CheckExpectedRanges("{ [0,19) }");
// Check for data in the track buffer. // Check for data in the track buffer.
...@@ -1537,12 +1535,12 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_NoKeyframeAfterNew2) { ...@@ -1537,12 +1535,12 @@ TEST_F(SourceBufferStreamTest, End_Overlap_Selected_NoKeyframeAfterNew2) {
// should contain DTS 16, PTS 19. // should contain DTS 16, PTS 19.
// Unlike the rest of the position based test API used in this case, // Unlike the rest of the position based test API used in this case,
// CheckExpectedRanges() uses expectation strings containing actual timestamps // CheckExpectedRanges() uses expectation strings containing actual timestamps
// (divided by frame_duration_), in DTS if ByDts, in PTS if ByPts. // (divided by frame_duration_).
CheckExpectedRanges("{ [5,15) }"); CheckExpectedRanges("{ [5,15) }");
// Now do another end-overlap. Append one full GOP plus keyframe of 2nd. // Now do another end-overlap. Append one full GOP plus keyframe of 2nd. Note
// Note that this new keyframe at (5, PTS=DTS) is continuous in both ByPts and // that this new keyframe at (5, PTS=DTS) is continuous with the overlapped
// ByDts with the overlapped range's next GOP (B) at (10, PTS=DTS). // range's next GOP (B) at (10, PTS=DTS).
NewCodedFrameGroupAppend(0, 6, &kDataA); NewCodedFrameGroupAppend(0, 6, &kDataA);
CheckExpectedRanges("{ [0,15) }"); CheckExpectedRanges("{ [0,15) }");
......
...@@ -8,10 +8,8 @@ ...@@ -8,10 +8,8 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "base/feature_list.h"
#include "base/logging.h" #include "base/logging.h"
#include "media/base/decrypt_config.h" #include "media/base/decrypt_config.h"
#include "media/base/media_switches.h"
#include "media/formats/mp4/box_definitions.h" #include "media/formats/mp4/box_definitions.h"
#include "media/formats/mp4/box_reader.h" #include "media/formats/mp4/box_reader.h"
#include "media/video/h264_parser.h" #include "media/video/h264_parser.h"
...@@ -358,15 +356,12 @@ bool AVCBitstreamConverter::ConvertAndAnalyzeFrame( ...@@ -358,15 +356,12 @@ bool AVCBitstreamConverter::ConvertAndAnalyzeFrame(
subsamples)); subsamples));
// |is_keyframe| may be incorrect. Analyze the frame to see if it is a // |is_keyframe| may be incorrect. Analyze the frame to see if it is a
// keyframe. |is_keyframe| will be used if the analysis is inconclusive or if // keyframe. |is_keyframe| will be used if the analysis is inconclusive.
// not kMseBufferByPts.
// Also, provide the analysis result to the caller via out parameter // Also, provide the analysis result to the caller via out parameter
// |analysis_result|. // |analysis_result|.
*analysis_result = Analyze(frame_buf, subsamples); *analysis_result = Analyze(frame_buf, subsamples);
if (base::FeatureList::IsEnabled(kMseBufferByPts) if (analysis_result->is_keyframe.value_or(is_keyframe)) {
? analysis_result->is_keyframe.value_or(is_keyframe)
: is_keyframe) {
// If this is a keyframe, we (re-)inject SPS and PPS headers at the start of // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of
// a frame. If subsample info is present, we also update the clear byte // a frame. If subsample info is present, we also update the clear byte
// count for that first subsample. // count for that first subsample.
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <vector> #include <vector>
#include "base/callback_helpers.h" #include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/math_constants.h" #include "base/numerics/math_constants.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -21,7 +20,6 @@ ...@@ -21,7 +20,6 @@
#include "media/base/audio_decoder_config.h" #include "media/base/audio_decoder_config.h"
#include "media/base/encryption_pattern.h" #include "media/base/encryption_pattern.h"
#include "media/base/encryption_scheme.h" #include "media/base/encryption_scheme.h"
#include "media/base/media_switches.h"
#include "media/base/media_tracks.h" #include "media/base/media_tracks.h"
#include "media/base/media_util.h" #include "media/base/media_util.h"
#include "media/base/stream_parser_buffer.h" #include "media/base/stream_parser_buffer.h"
...@@ -817,11 +815,7 @@ ParseResult MP4StreamParser::EnqueueSample(BufferQueueMap* buffers) { ...@@ -817,11 +815,7 @@ ParseResult MP4StreamParser::EnqueueSample(BufferQueueMap* buffers) {
// they mismatch. If other out-of-order codecs in mp4 (e.g. HEVC, DV) // they mismatch. If other out-of-order codecs in mp4 (e.g. HEVC, DV)
// implement keyframe analysis in their frame_bitstream_converter, we'll // implement keyframe analysis in their frame_bitstream_converter, we'll
// similarly trust that analysis instead of the mp4. // similarly trust that analysis instead of the mp4.
// We'll only use the analysis to override the MP4 keyframeness if is_keyframe = analysis.is_keyframe.value();
// |media::kMseBufferByPts| is enabled.
if (base::FeatureList::IsEnabled(kMseBufferByPts)) {
is_keyframe = analysis.is_keyframe.value();
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment