Commit 17dc5b8d authored by sergeyu@chromium.org's avatar sergeyu@chromium.org

Add media::StreamParser::InitParameter struct.

The new struct is used to pass parameters to StreamParser::InitCB. This
change makes it easier to add new parameters.

BUG=338529
R=acolwell@chromium.org

Review URL: https://codereview.chromium.org/254473006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266077 0039d316-1c4b-4281-b951-d872f2087c98
parent 3d811377
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
namespace media { namespace media {
StreamParser::InitParameters::InitParameters(base::TimeDelta duration)
: duration(duration),
auto_update_timestamp_offset(false) {
}
StreamParser::StreamParser() {} StreamParser::StreamParser() {}
StreamParser::~StreamParser() {} StreamParser::~StreamParser() {}
......
...@@ -46,24 +46,27 @@ class MEDIA_EXPORT StreamParser { ...@@ -46,24 +46,27 @@ class MEDIA_EXPORT StreamParser {
// Map of text track ID to decode-timestamp-ordered buffers for the track. // Map of text track ID to decode-timestamp-ordered buffers for the track.
typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap; typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap;
StreamParser(); // Stream parameters passed in InitCB.
virtual ~StreamParser(); struct InitParameters {
InitParameters(base::TimeDelta duration);
// Stream duration.
base::TimeDelta duration;
// Indicates the source time associated with presentation timestamp 0. A
// null Time is returned if no mapping to Time exists.
base::Time timeline_offset;
// Indicates that timestampOffset should be updated based on the earliest
// end timestamp (audio or video) provided during each NewBuffersCB.
bool auto_update_timestamp_offset;
};
// Indicates completion of parser initialization. // Indicates completion of parser initialization.
// First parameter - Indicates initialization success. Set to true if // success - True if initialization was successful.
// initialization was successful. False if an error // params - Stream parameters, in case of successful initialization.
// occurred. typedef base::Callback<void(bool success,
// Second parameter - Indicates the stream duration. Only contains a valid const InitParameters& params)> InitCB;
// value if the first parameter is true.
// Third parameter - Indicates the Time associated with
// presentation timestamp 0 if such a mapping exists in
// the bytestream. If no mapping exists this parameter
// contains null Time object. Only contains a valid
// value if the first parameter is true.
// Fourth parameters - Indicates that timestampOffset should be updated based
// on the earliest end timestamp (audio or video) provided
// during each NewBuffersCB.
typedef base::Callback<void(bool, base::TimeDelta, base::Time, bool)> InitCB;
// Indicates when new stream configurations have been parsed. // Indicates when new stream configurations have been parsed.
// First parameter - The new audio configuration. If the config is not valid // First parameter - The new audio configuration. If the config is not valid
...@@ -103,6 +106,9 @@ class MEDIA_EXPORT StreamParser { ...@@ -103,6 +106,9 @@ class MEDIA_EXPORT StreamParser {
typedef base::Callback<void(const std::string&, typedef base::Callback<void(const std::string&,
const std::vector<uint8>&)> NeedKeyCB; const std::vector<uint8>&)> NeedKeyCB;
StreamParser();
virtual ~StreamParser();
// Initializes the parser with necessary callbacks. Must be called before any // Initializes the parser with necessary callbacks. Must be called before any
// data is passed to Parse(). |init_cb| will be called once enough data has // data is passed to Parse(). |init_cb| will be called once enough data has
// been parsed to determine the initial stream configurations, presentation // been parsed to determine the initial stream configurations, presentation
......
...@@ -93,17 +93,6 @@ class SourceState { ...@@ -93,17 +93,6 @@ class SourceState {
typedef base::Callback<void( typedef base::Callback<void(
ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB; ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB;
// First parameter - Indicates initialization success. Set to true if
// initialization was successful. False if an error
// occurred.
// Second parameter - Indicates the stream duration. Only contains a valid
// value if the first parameter is true.
// Third parameter - Indicates the source Time associated with
// presentation timestamp 0. A null Time is returned if
// no mapping to Time exists. Only contains a
// valid value if the first parameter is true.
typedef base::Callback<void(bool, TimeDelta, base::Time)> InitCB;
SourceState( SourceState(
scoped_ptr<StreamParser> stream_parser, scoped_ptr<StreamParser> stream_parser,
scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb, scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb,
...@@ -111,7 +100,7 @@ class SourceState { ...@@ -111,7 +100,7 @@ class SourceState {
~SourceState(); ~SourceState();
void Init(const InitCB& init_cb, void Init(const StreamParser::InitCB& init_cb,
bool allow_audio, bool allow_audio,
bool allow_video, bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb, const StreamParser::NeedKeyCB& need_key_cb,
...@@ -193,9 +182,7 @@ class SourceState { ...@@ -193,9 +182,7 @@ class SourceState {
const StreamParser::TextBufferQueueMap& text_map); const StreamParser::TextBufferQueueMap& text_map);
void OnSourceInitDone(bool success, void OnSourceInitDone(bool success,
TimeDelta duration, const StreamParser::InitParameters& params);
base::Time timeline_offset,
bool auto_update_timestamp_offset);
CreateDemuxerStreamCB create_demuxer_stream_cb_; CreateDemuxerStreamCB create_demuxer_stream_cb_;
NewTextTrackCB new_text_track_cb_; NewTextTrackCB new_text_track_cb_;
...@@ -236,7 +223,7 @@ class SourceState { ...@@ -236,7 +223,7 @@ class SourceState {
scoped_ptr<FrameProcessorBase> frame_processor_; scoped_ptr<FrameProcessorBase> frame_processor_;
LogCB log_cb_; LogCB log_cb_;
InitCB init_cb_; StreamParser::InitCB init_cb_;
// Indicates that timestampOffset should be updated automatically during // Indicates that timestampOffset should be updated automatically during
// OnNewBuffers() based on the earliest end timestamp of the buffers provided. // OnNewBuffers() based on the earliest end timestamp of the buffers provided.
...@@ -269,7 +256,7 @@ SourceState::~SourceState() { ...@@ -269,7 +256,7 @@ SourceState::~SourceState() {
STLDeleteValues(&text_stream_map_); STLDeleteValues(&text_stream_map_);
} }
void SourceState::Init(const InitCB& init_cb, void SourceState::Init(const StreamParser::InitCB& init_cb,
bool allow_audio, bool allow_audio,
bool allow_video, bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb, const StreamParser::NeedKeyCB& need_key_cb,
...@@ -701,12 +688,9 @@ bool SourceState::OnNewBuffers( ...@@ -701,12 +688,9 @@ bool SourceState::OnNewBuffers(
} }
void SourceState::OnSourceInitDone(bool success, void SourceState::OnSourceInitDone(bool success,
TimeDelta duration, const StreamParser::InitParameters& params) {
base::Time timeline_offset, auto_update_timestamp_offset_ = params.auto_update_timestamp_offset;
bool auto_update_timestamp_offset) { base::ResetAndReturn(&init_cb_).Run(success, params);
auto_update_timestamp_offset_ = auto_update_timestamp_offset;
base::ResetAndReturn(&init_cb_).Run(
success, duration, timeline_offset);
} }
ChunkDemuxerStream::ChunkDemuxerStream(Type type, bool splice_frames_enabled) ChunkDemuxerStream::ChunkDemuxerStream(Type type, bool splice_frames_enabled)
...@@ -1497,10 +1481,11 @@ bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { ...@@ -1497,10 +1481,11 @@ bool ChunkDemuxer::IsSeekWaitingForData_Locked() const {
return false; return false;
} }
void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration, void ChunkDemuxer::OnSourceInitDone(
base::Time timeline_offset) { bool success,
const StreamParser::InitParameters& params) {
DVLOG(1) << "OnSourceInitDone(" << success << ", " DVLOG(1) << "OnSourceInitDone(" << success << ", "
<< duration.InSecondsF() << ")"; << params.duration.InSecondsF() << ")";
lock_.AssertAcquired(); lock_.AssertAcquired();
DCHECK_EQ(state_, INITIALIZING); DCHECK_EQ(state_, INITIALIZING);
if (!success || (!audio_ && !video_)) { if (!success || (!audio_ && !video_)) {
...@@ -1508,25 +1493,26 @@ void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration, ...@@ -1508,25 +1493,26 @@ void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration,
return; return;
} }
if (duration != TimeDelta() && duration_ == kNoTimestamp()) if (params.duration != TimeDelta() && duration_ == kNoTimestamp())
UpdateDuration(duration); UpdateDuration(params.duration);
if (!timeline_offset.is_null()) { if (!params.timeline_offset.is_null()) {
if (!timeline_offset_.is_null() && if (!timeline_offset_.is_null() &&
timeline_offset != timeline_offset_) { params.timeline_offset != timeline_offset_) {
MEDIA_LOG(log_cb_) MEDIA_LOG(log_cb_)
<< "Timeline offset is not the same across all SourceBuffers."; << "Timeline offset is not the same across all SourceBuffers.";
ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
return; return;
} }
timeline_offset_ = timeline_offset; timeline_offset_ = params.timeline_offset;
} }
// Wait until all streams have initialized. // Wait until all streams have initialized.
if ((!source_id_audio_.empty() && !audio_) || if ((!source_id_audio_.empty() && !audio_) ||
(!source_id_video_.empty() && !video_)) (!source_id_video_.empty() && !video_)) {
return; return;
}
SeekAllSources(GetStartTime()); SeekAllSources(GetStartTime());
StartReturningData(); StartReturningData();
......
...@@ -287,8 +287,8 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { ...@@ -287,8 +287,8 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
bool CanEndOfStream_Locked() const; bool CanEndOfStream_Locked() const;
// SourceState callbacks. // SourceState callbacks.
void OnSourceInitDone(bool success, base::TimeDelta duration, void OnSourceInitDone(bool success,
base::Time timeline_offset); const StreamParser::InitParameters& params);
// Creates a DemuxerStream for the specified |type|. // Creates a DemuxerStream for the specified |type|.
// Returns a new ChunkDemuxerStream instance if a stream of this type // Returns a new ChunkDemuxerStream instance if a stream of this type
......
...@@ -72,14 +72,13 @@ bool StreamParserTestBase::AppendDataInPieces(const uint8* data, ...@@ -72,14 +72,13 @@ bool StreamParserTestBase::AppendDataInPieces(const uint8* data,
return true; return true;
} }
void StreamParserTestBase::OnInitDone(bool success, void StreamParserTestBase::OnInitDone(
base::TimeDelta duration, bool success,
base::Time wallclock_timeline_offset, const StreamParser::InitParameters& params) {
bool auto_update_timestamp_offset) { EXPECT_TRUE(params.auto_update_timestamp_offset);
EXPECT_TRUE(auto_update_timestamp_offset);
DVLOG(1) << __FUNCTION__ << "(" << success << ", " DVLOG(1) << __FUNCTION__ << "(" << success << ", "
<< duration.InMilliseconds() << ", " << auto_update_timestamp_offset << params.duration.InMilliseconds() << ", "
<< ")"; << params.auto_update_timestamp_offset << ")";
} }
bool StreamParserTestBase::OnNewConfig( bool StreamParserTestBase::OnNewConfig(
......
...@@ -50,10 +50,7 @@ class StreamParserTestBase { ...@@ -50,10 +50,7 @@ class StreamParserTestBase {
private: private:
bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size); bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size);
void OnInitDone(bool success, void OnInitDone(bool success, const StreamParser::InitParameters& params);
base::TimeDelta duration,
base::Time wallclock_timeline_offset,
bool auto_update_timestamp_offset);
bool OnNewConfig(const AudioDecoderConfig& audio_config, bool OnNewConfig(const AudioDecoderConfig& audio_config,
const VideoDecoderConfig& video_config, const VideoDecoderConfig& video_config,
const StreamParser::TextTrackConfigMap& text_config); const StreamParser::TextTrackConfigMap& text_config);
......
...@@ -485,8 +485,8 @@ bool Mp2tStreamParser::FinishInitializationIfNeeded() { ...@@ -485,8 +485,8 @@ bool Mp2tStreamParser::FinishInitializationIfNeeded() {
// For Mpeg2 TS, the duration is not known. // For Mpeg2 TS, the duration is not known.
DVLOG(1) << "Mpeg2TS stream parser initialization done"; DVLOG(1) << "Mpeg2TS stream parser initialization done";
base::ResetAndReturn(&init_cb_).Run( base::ResetAndReturn(&init_cb_)
true, kInfiniteDuration(), base::Time(), false); .Run(true, InitParameters(kInfiniteDuration()));
is_initialized_ = true; is_initialized_ = true;
return true; return true;
......
...@@ -58,12 +58,10 @@ class Mp2tStreamParserTest : public testing::Test { ...@@ -58,12 +58,10 @@ class Mp2tStreamParserTest : public testing::Test {
} }
void OnInit(bool init_ok, void OnInit(bool init_ok,
base::TimeDelta duration, const StreamParser::InitParameters& params) {
base::Time wallclock_timeline_offset,
bool auto_update_timestamp_offset) {
DVLOG(1) << "OnInit: ok=" << init_ok DVLOG(1) << "OnInit: ok=" << init_ok
<< ", dur=" << duration.InMilliseconds() << ", dur=" << params.duration.InMilliseconds()
<< ", autoTimestampOffset=" << auto_update_timestamp_offset; << ", autoTimestampOffset=" << params.auto_update_timestamp_offset;
} }
bool OnNewConfig(const AudioDecoderConfig& ac, bool OnNewConfig(const AudioDecoderConfig& ac,
......
...@@ -288,20 +288,18 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { ...@@ -288,20 +288,18 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) {
RCHECK(config_cb_.Run(audio_config, video_config, TextTrackConfigMap())); RCHECK(config_cb_.Run(audio_config, video_config, TextTrackConfigMap()));
base::TimeDelta duration; StreamParser::InitParameters params(kInfiniteDuration());
if (moov_->extends.header.fragment_duration > 0) { if (moov_->extends.header.fragment_duration > 0) {
duration = TimeDeltaFromRational(moov_->extends.header.fragment_duration, params.duration = TimeDeltaFromRational(
moov_->header.timescale); moov_->extends.header.fragment_duration, moov_->header.timescale);
} else if (moov_->header.duration > 0 && } else if (moov_->header.duration > 0 &&
moov_->header.duration != kuint64max) { moov_->header.duration != kuint64max) {
duration = TimeDeltaFromRational(moov_->header.duration, params.duration =
moov_->header.timescale); TimeDeltaFromRational(moov_->header.duration, moov_->header.timescale);
} else {
duration = kInfiniteDuration();
} }
if (!init_cb_.is_null()) if (!init_cb_.is_null())
base::ResetAndReturn(&init_cb_).Run(true, duration, base::Time(), false); base::ResetAndReturn(&init_cb_).Run(true, params);
EmitNeedKeyIfNecessary(moov_->pssh); EmitNeedKeyIfNecessary(moov_->pssh);
return true; return true;
......
...@@ -58,12 +58,10 @@ class MP4StreamParserTest : public testing::Test { ...@@ -58,12 +58,10 @@ class MP4StreamParserTest : public testing::Test {
return true; return true;
} }
void InitF(bool init_ok, void InitF(bool init_ok, const StreamParser::InitParameters& params) {
base::TimeDelta duration, DVLOG(1) << "InitF: ok=" << init_ok
base::Time wallclock_timeline_offset, << ", dur=" << params.duration.InMilliseconds()
bool auto_update_timestamp_offset) { << ", autoTimestampOffset=" << params.auto_update_timestamp_offset;
DVLOG(1) << "InitF: ok=" << init_ok << ", dur=" << duration.InMilliseconds()
<< ", autoTimestampOffset=" << auto_update_timestamp_offset;
} }
bool NewConfigF(const AudioDecoderConfig& ac, bool NewConfigF(const AudioDecoderConfig& ac,
......
...@@ -222,9 +222,11 @@ int MPEGAudioStreamParserBase::ParseFrame(const uint8* data, ...@@ -222,9 +222,11 @@ int MPEGAudioStreamParserBase::ParseFrame(const uint8* data,
VideoDecoderConfig video_config; VideoDecoderConfig video_config;
bool success = config_cb_.Run(config_, video_config, TextTrackConfigMap()); bool success = config_cb_.Run(config_, video_config, TextTrackConfigMap());
if (!init_cb_.is_null()) if (!init_cb_.is_null()) {
base::ResetAndReturn(&init_cb_).Run( InitParameters params(kInfiniteDuration());
success, kInfiniteDuration(), base::Time(), true); params.auto_update_timestamp_offset = true;
base::ResetAndReturn(&init_cb_).Run(success, params);
}
if (!success) if (!success)
return -1; return -1;
......
...@@ -181,13 +181,15 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { ...@@ -181,13 +181,15 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) {
bytes_parsed += result; bytes_parsed += result;
double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0; double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0;
base::TimeDelta duration = kInfiniteDuration(); InitParameters params(kInfiniteDuration());
if (info_parser.duration() > 0) { if (info_parser.duration() > 0) {
int64 duration_in_us = info_parser.duration() * timecode_scale_in_us; int64 duration_in_us = info_parser.duration() * timecode_scale_in_us;
duration = base::TimeDelta::FromMicroseconds(duration_in_us); params.duration = base::TimeDelta::FromMicroseconds(duration_in_us);
} }
params.timeline_offset = info_parser.date_utc();
const AudioDecoderConfig& audio_config = tracks_parser.audio_decoder_config(); const AudioDecoderConfig& audio_config = tracks_parser.audio_decoder_config();
if (audio_config.is_encrypted()) if (audio_config.is_encrypted())
FireNeedKey(tracks_parser.audio_encryption_key_id()); FireNeedKey(tracks_parser.audio_encryption_key_id());
...@@ -219,8 +221,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { ...@@ -219,8 +221,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) {
ChangeState(kParsingClusters); ChangeState(kParsingClusters);
if (!init_cb_.is_null()) if (!init_cb_.is_null())
base::ResetAndReturn(&init_cb_).Run( base::ResetAndReturn(&init_cb_).Run(true, params);
true, duration, info_parser.date_utc(), false);
return bytes_parsed; return bytes_parsed;
} }
......
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