summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-19 11:39:00 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-19 11:39:00 +0000
commit2096a3454d28bb1b67233713a6434657a9781cb2 (patch)
treef8cdd51a3e8ad259968eb317020629eb569f94aa /media
parent22a74fef5947336f7f7845d95601bc40954d99d8 (diff)
downloadchromium_src-2096a3454d28bb1b67233713a6434657a9781cb2.zip
chromium_src-2096a3454d28bb1b67233713a6434657a9781cb2.tar.gz
chromium_src-2096a3454d28bb1b67233713a6434657a9781cb2.tar.bz2
Allow StreamParsers to request automatic timestampOffset updates.
Extends StreamParser::InitCB with a new parameter which indicates that SourceState::OnNewBuffers() should update the timestampOffset based on the earliest end time of returned buffers (accounting for any current appendWindow). To prevent doubling of the timestamps in conjuction with the update to timestampOffset, the MPEGStreamParserBase now resets the timestamp helper after each SendBuffers() call. Also adds missing pipeline integration tests for ADTS. BUG=353307 TEST=existing tests pass. Post mp3 append, timestampOffset is updated. Review URL: https://codereview.chromium.org/195973006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257932 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/run_all_perftests.cc1
-rw-r--r--media/base/run_all_unittests.cc1
-rw-r--r--media/base/stream_parser.h9
-rw-r--r--media/filters/chunk_demuxer.cc112
-rw-r--r--media/filters/pipeline_integration_test.cc75
-rw-r--r--media/formats/common/stream_parser_test_base.cc8
-rw-r--r--media/formats/common/stream_parser_test_base.h4
-rw-r--r--media/formats/mp2t/mp2t_stream_parser.cc2
-rw-r--r--media/formats/mp2t/mp2t_stream_parser_unittest.cc7
-rw-r--r--media/formats/mp4/mp4_stream_parser.cc2
-rw-r--r--media/formats/mp4/mp4_stream_parser_unittest.cc8
-rw-r--r--media/formats/mpeg/adts_stream_parser_unittest.cc32
-rw-r--r--media/formats/mpeg/mp3_stream_parser_unittest.cc32
-rw-r--r--media/formats/mpeg/mpeg_audio_stream_parser_base.cc3
-rw-r--r--media/formats/webm/webm_stream_parser.cc7
15 files changed, 223 insertions, 80 deletions
diff --git a/media/base/run_all_perftests.cc b/media/base/run_all_perftests.cc
index 119bef3..f9f53e7 100644
--- a/media/base/run_all_perftests.cc
+++ b/media/base/run_all_perftests.cc
@@ -40,6 +40,7 @@ void TestSuiteNoAtExit::Initialize() {
// present.
media::InitializeMediaLibraryForTesting();
CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ cmd_line->AppendSwitch(switches::kEnableADTSStreamParser);
cmd_line->AppendSwitch(switches::kEnableMP3StreamParser);
}
diff --git a/media/base/run_all_unittests.cc b/media/base/run_all_unittests.cc
index f1a0092..543098e 100644
--- a/media/base/run_all_unittests.cc
+++ b/media/base/run_all_unittests.cc
@@ -40,6 +40,7 @@ void TestSuiteNoAtExit::Initialize() {
// present.
media::InitializeMediaLibraryForTesting();
CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ cmd_line->AppendSwitch(switches::kEnableADTSStreamParser);
cmd_line->AppendSwitch(switches::kEnableMP3StreamParser);
}
diff --git a/media/base/stream_parser.h b/media/base/stream_parser.h
index 6e380aa..c5410e3 100644
--- a/media/base/stream_parser.h
+++ b/media/base/stream_parser.h
@@ -53,9 +53,12 @@ class MEDIA_EXPORT StreamParser {
// 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.
- typedef base::Callback<void(bool, base::TimeDelta)> InitCB;
+ // Second parameter - Indicates the stream duration. Only contains a valid
+ // value if the first parameter is true.
+ // Third 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, bool)> InitCB;
// Indicates when new stream configurations have been parsed.
// First parameter - The new audio configuration. If the config is not valid
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 17f1d96..697396b 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -24,6 +24,10 @@ using base::TimeDelta;
namespace media {
+static TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) {
+ return queue.back()->timestamp() + queue.back()->duration();
+}
+
// List of time ranges for each SourceBuffer.
typedef std::list<Ranges<TimeDelta> > RangesList;
static Ranges<TimeDelta> ComputeIntersection(const RangesList& activeRanges,
@@ -89,6 +93,13 @@ class SourceState {
typedef base::Callback<void(
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.
+ typedef base::Callback<void(bool, TimeDelta)> InitCB;
+
SourceState(
scoped_ptr<StreamParser> stream_parser,
scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb,
@@ -96,7 +107,7 @@ class SourceState {
~SourceState();
- void Init(const StreamParser::InitCB& init_cb,
+ void Init(const InitCB& init_cb,
bool allow_audio,
bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb,
@@ -177,6 +188,10 @@ class SourceState {
const StreamParser::BufferQueue& video_buffers,
const StreamParser::TextBufferQueueMap& text_map);
+ void OnSourceInitDone(bool success,
+ TimeDelta duration,
+ bool auto_update_timestamp_offset);
+
CreateDemuxerStreamCB create_demuxer_stream_cb_;
NewTextTrackCB new_text_track_cb_;
@@ -216,15 +231,19 @@ class SourceState {
scoped_ptr<FrameProcessorBase> frame_processor_;
LogCB log_cb_;
+ InitCB init_cb_;
+
+ // Indicates that timestampOffset should be updated automatically during
+ // OnNewBuffers() based on the earliest end timestamp of the buffers provided.
+ bool auto_update_timestamp_offset_;
DISALLOW_COPY_AND_ASSIGN(SourceState);
};
-SourceState::SourceState(
- scoped_ptr<StreamParser> stream_parser,
- scoped_ptr<FrameProcessorBase> frame_processor,
- const LogCB& log_cb,
- const CreateDemuxerStreamCB& create_demuxer_stream_cb)
+SourceState::SourceState(scoped_ptr<StreamParser> stream_parser,
+ scoped_ptr<FrameProcessorBase> frame_processor,
+ const LogCB& log_cb,
+ const CreateDemuxerStreamCB& create_demuxer_stream_cb)
: create_demuxer_stream_cb_(create_demuxer_stream_cb),
timestamp_offset_during_append_(NULL),
new_media_segment_(false),
@@ -233,7 +252,8 @@ SourceState::SourceState(
audio_(NULL),
video_(NULL),
frame_processor_(frame_processor.release()),
- log_cb_(log_cb) {
+ log_cb_(log_cb),
+ auto_update_timestamp_offset_(false) {
DCHECK(!create_demuxer_stream_cb_.is_null());
DCHECK(frame_processor_);
}
@@ -244,27 +264,26 @@ SourceState::~SourceState() {
STLDeleteValues(&text_stream_map_);
}
-void SourceState::Init(const StreamParser::InitCB& init_cb,
+void SourceState::Init(const InitCB& init_cb,
bool allow_audio,
bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb,
const NewTextTrackCB& new_text_track_cb) {
new_text_track_cb_ = new_text_track_cb;
-
- stream_parser_->Init(init_cb,
- base::Bind(&SourceState::OnNewConfigs,
- base::Unretained(this),
- allow_audio,
- allow_video),
- base::Bind(&SourceState::OnNewBuffers,
- base::Unretained(this)),
- new_text_track_cb_.is_null(),
- need_key_cb,
- base::Bind(&SourceState::OnNewMediaSegment,
- base::Unretained(this)),
- base::Bind(&SourceState::OnEndOfMediaSegment,
- base::Unretained(this)),
- log_cb_);
+ init_cb_ = init_cb;
+
+ stream_parser_->Init(
+ base::Bind(&SourceState::OnSourceInitDone, base::Unretained(this)),
+ base::Bind(&SourceState::OnNewConfigs,
+ base::Unretained(this),
+ allow_audio,
+ allow_video),
+ base::Bind(&SourceState::OnNewBuffers, base::Unretained(this)),
+ new_text_track_cb_.is_null(),
+ need_key_cb,
+ base::Bind(&SourceState::OnNewMediaSegment, base::Unretained(this)),
+ base::Bind(&SourceState::OnEndOfMediaSegment, base::Unretained(this)),
+ log_cb_);
}
void SourceState::SetSequenceMode(bool sequence_mode) {
@@ -638,10 +657,49 @@ bool SourceState::OnNewBuffers(
DVLOG(2) << "OnNewBuffers()";
DCHECK(timestamp_offset_during_append_);
- return frame_processor_->ProcessFrames(
- audio_buffers, video_buffers, text_map,
- append_window_start_during_append_, append_window_end_during_append_,
- &new_media_segment_, timestamp_offset_during_append_);
+ const TimeDelta timestamp_offset_before_processing =
+ *timestamp_offset_during_append_;
+
+ // Calculate the new timestamp offset for audio/video tracks if the stream
+ // parser has requested automatic updates.
+ TimeDelta new_timestamp_offset = timestamp_offset_before_processing;
+ if (auto_update_timestamp_offset_) {
+ const bool have_audio_buffers = !audio_buffers.empty();
+ const bool have_video_buffers = !video_buffers.empty();
+ if (have_audio_buffers && have_video_buffers) {
+ new_timestamp_offset +=
+ std::min(EndTimestamp(audio_buffers), EndTimestamp(video_buffers));
+ } else if (have_audio_buffers) {
+ new_timestamp_offset += EndTimestamp(audio_buffers);
+ } else if (have_video_buffers) {
+ new_timestamp_offset += EndTimestamp(video_buffers);
+ }
+ }
+
+ if (!frame_processor_->ProcessFrames(audio_buffers,
+ video_buffers,
+ text_map,
+ append_window_start_during_append_,
+ append_window_end_during_append_,
+ &new_media_segment_,
+ timestamp_offset_during_append_)) {
+ return false;
+ }
+
+ // Only update the timestamp offset if the frame processor hasn't already.
+ if (auto_update_timestamp_offset_ &&
+ timestamp_offset_before_processing == *timestamp_offset_during_append_) {
+ *timestamp_offset_during_append_ = new_timestamp_offset;
+ }
+
+ return true;
+}
+
+void SourceState::OnSourceInitDone(bool success,
+ TimeDelta duration,
+ bool auto_update_timestamp_offset) {
+ auto_update_timestamp_offset_ = auto_update_timestamp_offset;
+ base::ResetAndReturn(&init_cb_).Run(success, duration);
}
ChunkDemuxerStream::ChunkDemuxerStream(Type type)
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index eddf00e..05ba993 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -33,6 +33,7 @@ const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\"";
const char kMP4VideoType[] = "video/mp4";
const char kMP4AudioType[] = "audio/mp4";
#if defined(USE_PROPRIETARY_CODECS)
+const char kADTS[] = "audio/aac";
const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\"";
const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\"";
const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\"";
@@ -305,15 +306,17 @@ class MockMediaSource {
kSourceId, file_data_->data() + current_position_, size,
base::TimeDelta(), kInfiniteDuration(), &timestamp_offset);
current_position_ += size;
+ last_timestamp_offset_ = timestamp_offset;
}
- void AppendAtTime(const base::TimeDelta& timestampOffset,
- const uint8* pData, int size) {
- base::TimeDelta timestamp_offset = timestampOffset;
+ void AppendAtTime(base::TimeDelta timestamp_offset,
+ const uint8* pData,
+ int size) {
CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
chunk_demuxer_->AppendData(kSourceId, pData, size,
base::TimeDelta(), kInfiniteDuration(),
&timestamp_offset);
+ last_timestamp_offset_ = timestamp_offset;
}
void EndOfStream() {
@@ -369,6 +372,10 @@ class MockMediaSource {
need_key_cb_.Run(type, init_data);
}
+ base::TimeDelta last_timestamp_offset() const {
+ return last_timestamp_offset_;
+ }
+
private:
base::FilePath file_path_;
scoped_refptr<DecoderBuffer> file_data_;
@@ -378,6 +385,7 @@ class MockMediaSource {
ChunkDemuxer* chunk_demuxer_;
scoped_ptr<Demuxer> owned_chunk_demuxer_;
Demuxer::NeedKeyCB need_key_cb_;
+ base::TimeDelta last_timestamp_offset_;
};
class PipelineIntegrationTest
@@ -715,16 +723,77 @@ TEST_F(PipelineIntegrationTest,
}
#if defined(USE_PROPRIETARY_CODECS)
+TEST_F(PipelineIntegrationTest, MediaSource_ADTS) {
+ MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
+ StartPipelineWithMediaSource(&source);
+ source.EndOfStream();
+
+ EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+ EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+ EXPECT_EQ(325, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+ Play();
+
+ EXPECT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_ADTS_TimestampOffset) {
+ MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
+ StartPipelineWithMediaSource(&source);
+ EXPECT_EQ(325, source.last_timestamp_offset().InMilliseconds());
+
+ scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
+ source.AppendAtTime(
+ source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
+ second_file->data(),
+ second_file->data_size());
+ source.EndOfStream();
+
+ EXPECT_EQ(640, source.last_timestamp_offset().InMilliseconds());
+ EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+ EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+ EXPECT_EQ(640, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+ Play();
+
+ EXPECT_TRUE(WaitUntilOnEnded());
+}
+
TEST_F(PipelineIntegrationTest, MediaSource_MP3) {
MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
StartPipelineWithMediaSource(&source);
source.EndOfStream();
+ EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+ EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+ EXPECT_EQ(339, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
Play();
EXPECT_TRUE(WaitUntilOnEnded());
}
+TEST_F(PipelineIntegrationTest, MediaSource_MP3_TimestampOffset) {
+ MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
+ StartPipelineWithMediaSource(&source);
+ EXPECT_EQ(339, source.last_timestamp_offset().InMilliseconds());
+
+ scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
+ source.AppendAtTime(
+ source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
+ second_file->data(),
+ second_file->data_size());
+ source.EndOfStream();
+
+ EXPECT_EQ(669, source.last_timestamp_offset().InMilliseconds());
+ EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+ EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+ EXPECT_EQ(669, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+ Play();
+
+ EXPECT_TRUE(WaitUntilOnEnded());
+}
TEST_F(PipelineIntegrationTest, MediaSource_MP3_Icecast) {
MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile);
diff --git a/media/formats/common/stream_parser_test_base.cc b/media/formats/common/stream_parser_test_base.cc
index 40d39d6..abe7cf9 100644
--- a/media/formats/common/stream_parser_test_base.cc
+++ b/media/formats/common/stream_parser_test_base.cc
@@ -70,9 +70,13 @@ bool StreamParserTestBase::AppendDataInPieces(const uint8* data,
return true;
}
-void StreamParserTestBase::OnInitDone(bool success, base::TimeDelta duration) {
+void StreamParserTestBase::OnInitDone(bool success,
+ base::TimeDelta duration,
+ bool auto_update_timestamp_offset) {
+ EXPECT_TRUE(auto_update_timestamp_offset);
DVLOG(1) << __FUNCTION__ << "(" << success << ", "
- << duration.InMilliseconds() << ")";
+ << duration.InMilliseconds() << ", " << auto_update_timestamp_offset
+ << ")";
}
bool StreamParserTestBase::OnNewConfig(
diff --git a/media/formats/common/stream_parser_test_base.h b/media/formats/common/stream_parser_test_base.h
index a3385ff..780f665 100644
--- a/media/formats/common/stream_parser_test_base.h
+++ b/media/formats/common/stream_parser_test_base.h
@@ -43,7 +43,9 @@ class StreamParserTestBase {
void InitializeParser();
bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size);
- void OnInitDone(bool success, base::TimeDelta duration);
+ void OnInitDone(bool success,
+ base::TimeDelta duration,
+ bool auto_update_timestamp_offset);
bool OnNewConfig(const AudioDecoderConfig& audio_config,
const VideoDecoderConfig& video_config,
const StreamParser::TextTrackConfigMap& text_config);
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc
index 66bdf4f..a22af1a 100644
--- a/media/formats/mp2t/mp2t_stream_parser.cc
+++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -484,7 +484,7 @@ bool Mp2tStreamParser::FinishInitializationIfNeeded() {
// For Mpeg2 TS, the duration is not known.
DVLOG(1) << "Mpeg2TS stream parser initialization done";
- init_cb_.Run(true, kInfiniteDuration());
+ init_cb_.Run(true, kInfiniteDuration(), false);
is_initialized_ = true;
return true;
diff --git a/media/formats/mp2t/mp2t_stream_parser_unittest.cc b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
index 02370f2..ea79674 100644
--- a/media/formats/mp2t/mp2t_stream_parser_unittest.cc
+++ b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
@@ -57,9 +57,12 @@ class Mp2tStreamParserTest : public testing::Test {
return true;
}
- void OnInit(bool init_ok, base::TimeDelta duration) {
+ void OnInit(bool init_ok,
+ base::TimeDelta duration,
+ bool auto_update_timestamp_offset) {
DVLOG(1) << "OnInit: ok=" << init_ok
- << ", dur=" << duration.InMilliseconds();
+ << ", dur=" << duration.InMilliseconds()
+ << ", autoTimestampOffset=" << auto_update_timestamp_offset;
}
bool OnNewConfig(const AudioDecoderConfig& ac,
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc
index 809bd82..2fac274 100644
--- a/media/formats/mp4/mp4_stream_parser.cc
+++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -301,7 +301,7 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) {
}
if (!init_cb_.is_null())
- base::ResetAndReturn(&init_cb_).Run(true, duration);
+ base::ResetAndReturn(&init_cb_).Run(true, duration, false);
EmitNeedKeyIfNecessary(moov_->pssh);
return true;
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc
index f86a5b0..226943e 100644
--- a/media/formats/mp4/mp4_stream_parser_unittest.cc
+++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -58,9 +58,11 @@ class MP4StreamParserTest : public testing::Test {
return true;
}
- void InitF(bool init_ok, base::TimeDelta duration) {
- DVLOG(1) << "InitF: ok=" << init_ok
- << ", dur=" << duration.InMilliseconds();
+ void InitF(bool init_ok,
+ base::TimeDelta duration,
+ bool auto_update_timestamp_offset) {
+ DVLOG(1) << "InitF: ok=" << init_ok << ", dur=" << duration.InMilliseconds()
+ << ", autoTimestampOffset=" << auto_update_timestamp_offset;
}
bool NewConfigF(const AudioDecoderConfig& ac,
diff --git a/media/formats/mpeg/adts_stream_parser_unittest.cc b/media/formats/mpeg/adts_stream_parser_unittest.cc
index d0bedbe..b9eb0d9 100644
--- a/media/formats/mpeg/adts_stream_parser_unittest.cc
+++ b/media/formats/mpeg/adts_stream_parser_unittest.cc
@@ -22,21 +22,21 @@ TEST_F(ADTSStreamParserTest, UnalignedAppend) {
const std::string expected =
"NewSegment"
"{ 0K }"
- "{ 23K }"
- "{ 46K }"
- "{ 69K }"
- "{ 92K }"
- "{ 116K }"
- "{ 139K }"
- "{ 162K }"
- "{ 185K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
"EndOfSegment"
"NewSegment"
- "{ 208K }"
- "{ 232K }"
- "{ 255K }"
- "{ 278K }"
- "{ 301K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
"EndOfSegment";
EXPECT_EQ(expected, ParseFile("sfx.adts", 17));
}
@@ -47,11 +47,11 @@ TEST_F(ADTSStreamParserTest, UnalignedAppend512) {
const std::string expected =
"NewSegment"
"{ 0K 23K 46K }"
- "{ 69K 92K 116K 139K 162K }"
- "{ 185K 208K 232K 255K 278K }"
+ "{ 0K 23K 46K 69K 92K }"
+ "{ 0K 23K 46K 69K 92K }"
"EndOfSegment"
"NewSegment"
- "{ 301K }"
+ "{ 0K }"
"EndOfSegment";
EXPECT_EQ(expected, ParseFile("sfx.adts", 512));
}
diff --git a/media/formats/mpeg/mp3_stream_parser_unittest.cc b/media/formats/mpeg/mp3_stream_parser_unittest.cc
index eefadc5..85cc129 100644
--- a/media/formats/mpeg/mp3_stream_parser_unittest.cc
+++ b/media/formats/mpeg/mp3_stream_parser_unittest.cc
@@ -22,22 +22,22 @@ TEST_F(MP3StreamParserTest, UnalignedAppend) {
const std::string expected =
"NewSegment"
"{ 0K }"
- "{ 26K }"
- "{ 52K }"
- "{ 78K }"
- "{ 104K }"
- "{ 130K }"
- "{ 156K }"
- "{ 182K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
"EndOfSegment"
"NewSegment"
- "{ 208K }"
- "{ 235K }"
- "{ 261K }"
+ "{ 0K }"
+ "{ 0K }"
+ "{ 0K }"
"EndOfSegment"
"NewSegment"
- "{ 287K }"
- "{ 313K }"
+ "{ 0K }"
+ "{ 0K }"
"EndOfSegment";
EXPECT_EQ(expected, ParseFile("sfx.mp3", 17));
}
@@ -48,12 +48,12 @@ TEST_F(MP3StreamParserTest, UnalignedAppend512) {
const std::string expected =
"NewSegment"
"{ 0K }"
- "{ 26K 52K 78K 104K }"
+ "{ 0K 26K 52K 78K }"
"EndOfSegment"
"NewSegment"
- "{ 130K 156K 182K }"
- "{ 208K 235K 261K 287K }"
- "{ 313K }"
+ "{ 0K 26K 52K }"
+ "{ 0K 26K 52K 78K }"
+ "{ 0K }"
"EndOfSegment";
EXPECT_EQ(expected, ParseFile("sfx.mp3", 512));
}
diff --git a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
index ba3cbd9..aaf6a50 100644
--- a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
+++ b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
@@ -208,7 +208,7 @@ int MPEGAudioStreamParserBase::ParseFrame(const uint8* data,
bool success = config_cb_.Run(config_, video_config, TextTrackConfigMap());
if (!init_cb_.is_null())
- base::ResetAndReturn(&init_cb_).Run(success, kInfiniteDuration());
+ base::ResetAndReturn(&init_cb_).Run(success, kInfiniteDuration(), true);
if (!success)
return -1;
@@ -393,6 +393,7 @@ bool MPEGAudioStreamParserBase::SendBuffers(BufferQueue* buffers,
end_of_segment_cb_.Run();
}
+ timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
return true;
}
diff --git a/media/formats/webm/webm_stream_parser.cc b/media/formats/webm/webm_stream_parser.cc
index fcb55de..eae0371 100644
--- a/media/formats/webm/webm_stream_parser.cc
+++ b/media/formats/webm/webm_stream_parser.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/callback.h"
+#include "base/callback_helpers.h"
#include "base/logging.h"
#include "media/formats/webm/webm_cluster_parser.h"
#include "media/formats/webm/webm_constants.h"
@@ -214,10 +215,8 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) {
ChangeState(kParsingClusters);
- if (!init_cb_.is_null()) {
- init_cb_.Run(true, duration);
- init_cb_.Reset();
- }
+ if (!init_cb_.is_null())
+ base::ResetAndReturn(&init_cb_).Run(true, duration, false);
return bytes_parsed;
}