Skip to content

Commit

Permalink
MSE: Vary ChunkDemuxer{Stream} of ByDts/ByPts based on media::kMseBuf…
Browse files Browse the repository at this point in the history
…ferByPts

Also adds kMseBufferByPts feature variation to SourceBufferStateTests
(since they construct ChunkDemuxerStreams, too).

Also includes some clean-up of SourceBufferStream enums (extracting
Status and Type from template-specialization to simplify usage.)

BUG=718641

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I5531b8b9fbf10c5c6b2137fd436ba53a99526963
Reviewed-on: https://chromium-review.googlesource.com/675987
Reviewed-by: Chrome Cunningham <chcunningham@chromium.org>
Commit-Queue: Matthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#503472}
  • Loading branch information
wolenetz authored and Commit Bot committed Sep 21, 2017
1 parent 5df91b2 commit 8aa773b
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 208 deletions.
110 changes: 69 additions & 41 deletions media/filters/chunk_demuxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,35 @@

using base::TimeDelta;

// This macro determines which SourceBufferStream member various
// ChunkDemuxerStream methods use based on the buffering API |range_api_| set at
// construction time. See https://crbug.com/718641.
#define SBSTREAM_IS_SET \
(range_api_ == RangeApi::kLegacyByDts ? stream_dts_ != nullptr \
: stream_pts_ != nullptr)

#define SBSTREAM_OP(operation) \
(range_api_ == RangeApi::kLegacyByDts ? stream_dts_->operation \
: stream_pts_->operation)

#define SBSTREAM_RESET(config, log) \
{ \
if (range_api_ == RangeApi::kLegacyByDts) { \
stream_dts_.reset( \
new SourceBufferStream<SourceBufferRangeByDts>(config, log)); \
} else { \
stream_pts_.reset( \
new SourceBufferStream<SourceBufferRangeByPts>(config, log)); \
} \
}

namespace media {

ChunkDemuxerStream::ChunkDemuxerStream(Type type,
MediaTrack::Id media_track_id)
MediaTrack::Id media_track_id,
RangeApi range_api)
: type_(type),
range_api_(range_api),
liveness_(DemuxerStream::LIVENESS_UNKNOWN),
media_track_id_(media_track_id),
state_(UNINITIALIZED),
Expand Down Expand Up @@ -84,7 +108,7 @@ bool ChunkDemuxerStream::IsSeekWaitingForData() const {
// SourceBufferState::IsSeekWaitingForData().
DCHECK_NE(type_, DemuxerStream::TEXT);

return stream_->IsSeekPending();
return SBSTREAM_OP(IsSeekPending());
}

void ChunkDemuxerStream::Seek(TimeDelta time) {
Expand All @@ -94,7 +118,7 @@ void ChunkDemuxerStream::Seek(TimeDelta time) {
DCHECK(state_ == UNINITIALIZED || state_ == RETURNING_ABORT_FOR_READS)
<< state_;

stream_->Seek(time);
SBSTREAM_OP(Seek(time));
}

bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {
Expand All @@ -103,7 +127,7 @@ bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {

base::AutoLock auto_lock(lock_);
DCHECK_NE(state_, SHUTDOWN);
if (!stream_->Append(buffers)) {
if (!SBSTREAM_OP(Append(buffers))) {
DVLOG(1) << "ChunkDemuxerStream::Append() : stream append failed";
return false;
}
Expand All @@ -117,7 +141,7 @@ bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {
void ChunkDemuxerStream::Remove(TimeDelta start, TimeDelta end,
TimeDelta duration) {
base::AutoLock auto_lock(lock_);
stream_->Remove(start, end, duration);
SBSTREAM_OP(Remove(start, end, duration));
}

bool ChunkDemuxerStream::EvictCodedFrames(base::TimeDelta media_time,
Expand All @@ -131,28 +155,28 @@ bool ChunkDemuxerStream::EvictCodedFrames(base::TimeDelta media_time,
// to collect unnecessary data that is earlier than the GOP containing
// |media_time|.
if (!is_enabled_)
stream_->Seek(media_time);
SBSTREAM_OP(Seek(media_time));

// Note: The direct conversion from PTS to DTS is safe here, since we don't
// need to know currentTime precisely for GC. GC only needs to know which GOP
// currentTime points to.
DecodeTimestamp media_time_dts =
DecodeTimestamp::FromPresentationTime(media_time);
return stream_->GarbageCollectIfNeeded(media_time_dts, newDataSize);
return SBSTREAM_OP(GarbageCollectIfNeeded(media_time_dts, newDataSize));
}

void ChunkDemuxerStream::OnMemoryPressure(
DecodeTimestamp media_time,
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
bool force_instant_gc) {
base::AutoLock auto_lock(lock_);
return stream_->OnMemoryPressure(media_time, memory_pressure_level,
force_instant_gc);
return SBSTREAM_OP(
OnMemoryPressure(media_time, memory_pressure_level, force_instant_gc));
}

void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) {
base::AutoLock auto_lock(lock_);
stream_->OnSetDuration(duration);
SBSTREAM_OP(OnSetDuration(duration));
}

Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
Expand All @@ -169,7 +193,7 @@ Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
return text_range;
}

Ranges<TimeDelta> range = stream_->GetBufferedTime();
Ranges<TimeDelta> range = SBSTREAM_OP(GetBufferedTime());

if (range.size() == 0u)
return range;
Expand All @@ -183,31 +207,31 @@ Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
}

TimeDelta ChunkDemuxerStream::GetHighestPresentationTimestamp() const {
return stream_->GetHighestPresentationTimestamp();
return SBSTREAM_OP(GetHighestPresentationTimestamp());
}

TimeDelta ChunkDemuxerStream::GetBufferedDuration() const {
return stream_->GetBufferedDuration();
return SBSTREAM_OP(GetBufferedDuration());
}

size_t ChunkDemuxerStream::GetBufferedSize() const {
return stream_->GetBufferedSize();
return SBSTREAM_OP(GetBufferedSize());
}

void ChunkDemuxerStream::OnStartOfCodedFrameGroup(
DecodeTimestamp start_timestamp) {
DVLOG(2) << "ChunkDemuxerStream::OnStartOfCodedFrameGroup("
<< start_timestamp.InSecondsF() << ")";
base::AutoLock auto_lock(lock_);
stream_->OnStartOfCodedFrameGroup(start_timestamp);
SBSTREAM_OP(OnStartOfCodedFrameGroup(start_timestamp));
}

bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config,
MediaLog* media_log) {
DCHECK(config.IsValidConfig());
DCHECK_EQ(type_, AUDIO);
base::AutoLock auto_lock(lock_);
if (!stream_) {
if (!SBSTREAM_IS_SET) {
DCHECK_EQ(state_, UNINITIALIZED);

// FLAC in MSE here is only supported if in ISOBMFF, which has feature flag.
Expand All @@ -222,11 +246,11 @@ bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config,
config.codec() == kCodecMP3 || config.codec() == kCodecAAC ||
config.codec() == kCodecVorbis || config.codec() == kCodecFLAC;

stream_.reset(new StreamType(config, media_log));
SBSTREAM_RESET(config, media_log);
return true;
}

return stream_->UpdateAudioConfig(config);
return SBSTREAM_OP(UpdateAudioConfig(config));
}

bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config,
Expand All @@ -235,32 +259,32 @@ bool ChunkDemuxerStream::UpdateVideoConfig(const VideoDecoderConfig& config,
DCHECK_EQ(type_, VIDEO);
base::AutoLock auto_lock(lock_);

if (!stream_) {
if (!SBSTREAM_IS_SET) {
DCHECK_EQ(state_, UNINITIALIZED);
stream_.reset(new StreamType(config, media_log));
SBSTREAM_RESET(config, media_log);
return true;
}

return stream_->UpdateVideoConfig(config);
return SBSTREAM_OP(UpdateVideoConfig(config));
}

void ChunkDemuxerStream::UpdateTextConfig(const TextTrackConfig& config,
MediaLog* media_log) {
DCHECK_EQ(type_, TEXT);
base::AutoLock auto_lock(lock_);
DCHECK(!stream_);
DCHECK(!SBSTREAM_IS_SET);
DCHECK_EQ(state_, UNINITIALIZED);
stream_.reset(new StreamType(config, media_log));
SBSTREAM_RESET(config, media_log);
}

void ChunkDemuxerStream::MarkEndOfStream() {
base::AutoLock auto_lock(lock_);
stream_->MarkEndOfStream();
SBSTREAM_OP(MarkEndOfStream());
}

void ChunkDemuxerStream::UnmarkEndOfStream() {
base::AutoLock auto_lock(lock_);
stream_->UnmarkEndOfStream();
SBSTREAM_OP(UnmarkEndOfStream());
}

// DemuxerStream methods.
Expand Down Expand Up @@ -292,16 +316,16 @@ AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() {
CHECK_EQ(type_, AUDIO);
base::AutoLock auto_lock(lock_);
// Trying to track down crash. http://crbug.com/715761
CHECK(stream_);
return stream_->GetCurrentAudioDecoderConfig();
CHECK(SBSTREAM_IS_SET);
return SBSTREAM_OP(GetCurrentAudioDecoderConfig());
}

VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() {
CHECK_EQ(type_, VIDEO);
base::AutoLock auto_lock(lock_);
// Trying to track down crash. http://crbug.com/715761
CHECK(stream_);
return stream_->GetCurrentVideoDecoderConfig();
CHECK(SBSTREAM_IS_SET);
return SBSTREAM_OP(GetCurrentVideoDecoderConfig());
}

bool ChunkDemuxerStream::SupportsConfigChanges() { return true; }
Expand All @@ -323,8 +347,8 @@ void ChunkDemuxerStream::SetEnabled(bool enabled, base::TimeDelta timestamp) {

is_enabled_ = enabled;
if (enabled) {
DCHECK(stream_);
stream_->Seek(timestamp);
DCHECK(SBSTREAM_IS_SET);
SBSTREAM_OP(Seek(timestamp));
} else if (!read_cb_.is_null()) {
DVLOG(1) << "Read from disabled stream, returning EOS";
base::ResetAndReturn(&read_cb_).Run(kOk,
Expand All @@ -343,11 +367,11 @@ void ChunkDemuxerStream::SetStreamStatusChangeCB(
TextTrackConfig ChunkDemuxerStream::text_track_config() {
CHECK_EQ(type_, TEXT);
base::AutoLock auto_lock(lock_);
return stream_->GetCurrentTextTrackConfig();
return SBSTREAM_OP(GetCurrentTextTrackConfig());
}

void ChunkDemuxerStream::SetStreamMemoryLimit(size_t memory_limit) {
stream_->set_memory_limit(memory_limit);
SBSTREAM_OP(set_memory_limit(memory_limit));
}

void ChunkDemuxerStream::SetLiveness(Liveness liveness) {
Expand Down Expand Up @@ -377,27 +401,27 @@ void ChunkDemuxerStream::CompletePendingReadIfPossible_Locked() {
NOTREACHED();
return;
case RETURNING_DATA_FOR_READS:
switch (stream_->GetNextBuffer(&buffer)) {
case StreamType::kSuccess:
switch (SBSTREAM_OP(GetNextBuffer(&buffer))) {
case SourceBufferStreamStatus::kSuccess:
status = DemuxerStream::kOk;
DVLOG(2) << __func__ << ": returning kOk, type " << type_ << ", dts "
<< buffer->GetDecodeTimestamp().InSecondsF() << ", pts "
<< buffer->timestamp().InSecondsF() << ", dur "
<< buffer->duration().InSecondsF() << ", key "
<< buffer->is_key_frame();
break;
case StreamType::kNeedBuffer:
case SourceBufferStreamStatus::kNeedBuffer:
// Return early without calling |read_cb_| since we don't have
// any data to return yet.
DVLOG(2) << __func__ << ": returning kNeedBuffer, type " << type_;
return;
case StreamType::kEndOfStream:
case SourceBufferStreamStatus::kEndOfStream:
status = DemuxerStream::kOk;
buffer = StreamParserBuffer::CreateEOSBuffer();
DVLOG(2) << __func__ << ": returning kOk with EOS buffer, type "
<< type_;
break;
case StreamType::kConfigChange:
case SourceBufferStreamStatus::kConfigChange:
status = kConfigChanged;
buffer = NULL;
DVLOG(2) << __func__ << ": returning kConfigChange, type " << type_;
Expand Down Expand Up @@ -440,7 +464,8 @@ ChunkDemuxer::ChunkDemuxer(
liveness_(DemuxerStream::LIVENESS_UNKNOWN),
detected_audio_track_count_(0),
detected_video_track_count_(0),
detected_text_track_count_(0) {
detected_text_track_count_(0),
buffering_by_pts_(base::FeatureList::IsEnabled(kMseBufferByPts)) {
DCHECK(!open_cb_.is_null());
DCHECK(!encrypted_media_init_data_cb_.is_null());
}
Expand All @@ -452,7 +477,7 @@ std::string ChunkDemuxer::GetDisplayName() const {
void ChunkDemuxer::Initialize(DemuxerHost* host,
const PipelineStatusCB& init_cb,
bool enable_text_tracks) {
DVLOG(1) << "Init()";
DVLOG(1) << "Init(), buffering_by_pts_=" << buffering_by_pts_;

base::AutoLock auto_lock(lock_);
if (state_ == SHUTDOWN) {
Expand Down Expand Up @@ -1258,7 +1283,10 @@ ChunkDemuxerStream* ChunkDemuxer::CreateDemuxerStream(
}

std::unique_ptr<ChunkDemuxerStream> stream =
base::MakeUnique<ChunkDemuxerStream>(type, media_track_id);
base::MakeUnique<ChunkDemuxerStream>(
type, media_track_id,
(buffering_by_pts_ ? ChunkDemuxerStream::RangeApi::kNewByPts
: ChunkDemuxerStream::RangeApi::kLegacyByDts));
DCHECK(track_id_to_demux_stream_map_.find(media_track_id) ==
track_id_to_demux_stream_map_.end());
track_id_to_demux_stream_map_[media_track_id] = stream.get();
Expand Down
20 changes: 15 additions & 5 deletions media/filters/chunk_demuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "media/base/stream_parser.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_stream.h"

Expand All @@ -35,11 +36,11 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream {
public:
using BufferQueue = base::circular_deque<scoped_refptr<StreamParserBuffer>>;

// TODO(wolenetz): Vary the buffering API used by the stream. See
// https://crbug.com/718641.
using StreamType = SourceBufferStream<SourceBufferRangeByDts>;
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 control methods.
Expand Down Expand Up @@ -153,10 +154,14 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream {

// Specifies the type of the stream.
Type type_;
const RangeApi range_api_;

Liveness liveness_;

std::unique_ptr<StreamType> stream_;
// Precisely one of these will be used by an instance, determined by
// |range_api_| set in ctor. See https://crbug.com/718641.
std::unique_ptr<SourceBufferStream<SourceBufferRangeByDts>> stream_dts_;
std::unique_ptr<SourceBufferStream<SourceBufferRangeByPts>> stream_pts_;

const MediaTrack::Id media_track_id_;

Expand Down Expand Up @@ -466,6 +471,11 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
int detected_video_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_;

std::map<MediaTrack::Id, ChunkDemuxerStream*> track_id_to_demux_stream_map_;

DISALLOW_COPY_AND_ASSIGN(ChunkDemuxer);
Expand Down
Loading

0 comments on commit 8aa773b

Please sign in to comment.