summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-17 01:34:26 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-17 01:34:26 +0000
commitb3c4717987eb4a42ed2c24cf38df21ad1afbb7ed (patch)
tree8ac0e971649f0adf6caa787bbed29fbdc39aeb73
parent9a491bd864f97e71a6f978477eedefc242621d8f (diff)
downloadchromium_src-b3c4717987eb4a42ed2c24cf38df21ad1afbb7ed.zip
chromium_src-b3c4717987eb4a42ed2c24cf38df21ad1afbb7ed.tar.gz
chromium_src-b3c4717987eb4a42ed2c24cf38df21ad1afbb7ed.tar.bz2
Add frame hashing to PipelineIntegrationTests.
Also adds support for disabling frame dropping in the video renderer so we can be sure we've seen every frame coming out. Testing shows that there are issues with threading in the FFmpeg H264 decoder. Running with --video-threads=1 will yield different results than running multithreaded. We should probably increase the breadth of our basic playback testing once we've got a better handle on threaded decoding in FFmpeg. BUG=118688 TEST=media_unittests, ffmpeg_regression_tests. Review URL: http://codereview.chromium.org/9716008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127320 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/ffmpeg/ffmpeg_regression_tests.cc152
-rw-r--r--media/filters/pipeline_integration_test.cc1
-rw-r--r--media/filters/pipeline_integration_test_base.cc29
-rw-r--r--media/filters/pipeline_integration_test_base.h14
-rw-r--r--media/filters/video_renderer_base.cc7
-rw-r--r--media/filters/video_renderer_base.h7
-rw-r--r--media/filters/video_renderer_base_unittest.cc3
-rw-r--r--media/tools/player_wtl/view.h10
-rw-r--r--media/tools/player_x11/player_x11.cc3
-rw-r--r--webkit/media/webmediaplayer_impl.cc3
10 files changed, 153 insertions, 76 deletions
diff --git a/media/ffmpeg/ffmpeg_regression_tests.cc b/media/ffmpeg/ffmpeg_regression_tests.cc
index a145bdd..ae17dac 100644
--- a/media/ffmpeg/ffmpeg_regression_tests.cc
+++ b/media/ffmpeg/ffmpeg_regression_tests.cc
@@ -29,12 +29,14 @@ namespace media {
struct RegressionTestData {
RegressionTestData(const char* filename, PipelineStatus init_status,
- PipelineStatus end_status)
- : filename(filename),
+ PipelineStatus end_status, const char *md5)
+ : md5(md5),
+ filename(filename),
init_status(init_status),
end_status(end_status) {
}
+ const char* md5;
const char* filename;
PipelineStatus init_status;
PipelineStatus end_status;
@@ -45,119 +47,146 @@ class FFmpegRegressionTest
public PipelineIntegrationTestBase {
};
-#define FFMPEG_TEST_CASE(name, fn, init_status, end_status) \
+#define FFMPEG_TEST_CASE(name, fn, init_status, end_status, md5) \
INSTANTIATE_TEST_CASE_P(name, FFmpegRegressionTest, \
testing::Values(RegressionTestData(fn, \
init_status, \
- end_status)));
+ end_status, \
+ md5)));
// Test cases from issues.
-FFMPEG_TEST_CASE(Cr47325, "security/47325.mp4", PIPELINE_OK, PIPELINE_OK);
-FFMPEG_TEST_CASE(Cr93620, "security/93620.ogg", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr47325, "security/47325.mp4", PIPELINE_OK, PIPELINE_OK,
+ "bdb3976d86c531b43a4c9d43fa5e7dc2");
+FFMPEG_TEST_CASE(Cr93620, "security/93620.ogg", PIPELINE_OK, PIPELINE_OK,
+ kNullVideoHash);
FFMPEG_TEST_CASE(Cr100492, "security/100492.webm", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED);
-FFMPEG_TEST_CASE(Cr100543, "security/100543.webm", PIPELINE_OK, PIPELINE_OK);
+ DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash);
+FFMPEG_TEST_CASE(Cr100543, "security/100543.webm", PIPELINE_OK, PIPELINE_OK,
+ "17d7079458ef351b813c100ce87afbe6");
FFMPEG_TEST_CASE(Cr101458, "security/101458.webm", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED);
-FFMPEG_TEST_CASE(Cr108416, "security/108416.webm", PIPELINE_OK, PIPELINE_OK);
+ DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash);
+FFMPEG_TEST_CASE(Cr108416, "security/108416.webm", PIPELINE_OK, PIPELINE_OK,
+ "d5559b43d7406aac33bfeafceaf86fe9");
FFMPEG_TEST_CASE(Cr110849, "security/110849.mkv", DEMUXER_ERROR_COULD_NOT_PARSE,
- DEMUXER_ERROR_COULD_NOT_PARSE);
+ DEMUXER_ERROR_COULD_NOT_PARSE, kNullVideoHash);
FFMPEG_TEST_CASE(Cr112384, "security/112384.webm",
- DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_COULD_NOT_PARSE);
+ DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_COULD_NOT_PARSE,
+ kNullVideoHash);
FFMPEG_TEST_CASE(Cr112670, "security/112670.mp4", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE);
-FFMPEG_TEST_CASE(Cr112976, "security/112976.ogg", PIPELINE_OK, PIPELINE_OK);
+ PIPELINE_ERROR_DECODE, kNullVideoHash);
+FFMPEG_TEST_CASE(Cr112976, "security/112976.ogg", PIPELINE_OK, PIPELINE_OK,
+ kNullVideoHash);
FFMPEG_TEST_CASE(Cr116927, "security/116927.ogv", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE);
+ PIPELINE_ERROR_DECODE, kNullVideoHash);
// General MKV test cases.
FFMPEG_TEST_CASE(MKV_0, "security/nested_tags_lang.mka.627.628", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, kNullVideoHash);
FFMPEG_TEST_CASE(MKV_1, "security/nested_tags_lang.mka.667.628", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, kNullVideoHash);
// General MP4 test cases.
-FFMPEG_TEST_CASE(MP4_0, "security/aac.10419.mp4", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(MP4_0, "security/aac.10419.mp4", PIPELINE_OK, PIPELINE_OK,
+ kNullVideoHash);
FFMPEG_TEST_CASE(MP4_1, "security/clockh264aac_200021889.mp4",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN);
+ DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
+ kNullVideoHash);
FFMPEG_TEST_CASE(MP4_2, "security/clockh264aac_200701257.mp4", PIPELINE_OK,
- PIPELINE_OK);
-FFMPEG_TEST_CASE(MP4_4, "security/clockh264aac_301350139.mp4", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, kNullVideoHash);
FFMPEG_TEST_CASE(MP4_5, "security/clockh264aac_3022500.mp4",
DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
- DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS, kNullVideoHash);
FFMPEG_TEST_CASE(MP4_6, "security/clockh264aac_344289.mp4", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, kNullVideoHash);
FFMPEG_TEST_CASE(MP4_7, "security/clockh264mp3_187697.mp4", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, kNullVideoHash);
FFMPEG_TEST_CASE(MP4_8, "security/h264.705767.mp4", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE);
+ PIPELINE_ERROR_DECODE, kNullVideoHash);
FFMPEG_TEST_CASE(MP4_9, "security/smclockmp4aac_1_0.mp4",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN);
+ DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
+ kNullVideoHash);
// General OGV test cases.
FFMPEG_TEST_CASE(OGV_1, "security/out.163.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash);
FFMPEG_TEST_CASE(OGV_2, "security/out.391.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash);
FFMPEG_TEST_CASE(OGV_5, "security/smclocktheora_1_0.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_7, "security/smclocktheora_1_102.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_8, "security/smclocktheora_1_104.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_9, "security/smclocktheora_1_110.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_10, "security/smclocktheora_1_179.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_11, "security/smclocktheora_1_20.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_12, "security/smclocktheora_1_723.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_14, "security/smclocktheora_2_10405.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_15, "security/smclocktheora_2_10619.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_16, "security/smclocktheora_2_1075.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_17, "security/vorbis.482086.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(OGV_18, "security/wav.711.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash);
// General WebM test cases.
-FFMPEG_TEST_CASE(WEBM_1, "security/no-bug.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(WEBM_1, "security/no-bug.webm", PIPELINE_OK, PIPELINE_OK,
+ "20536f9ce571c5830bb7c782584223fd");
FFMPEG_TEST_CASE(WEBM_2, "security/uninitialize.webm", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE);
+ PIPELINE_ERROR_DECODE, kNullVideoHash);
FFMPEG_TEST_CASE(WEBM_3, "security/out.webm.139771.2965",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(WEBM_4, "security/out.webm.68798.1929",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED);
+ DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
+ kNullVideoHash);
FFMPEG_TEST_CASE(WEBM_5, "content/frame_size_change.webm", PIPELINE_OK,
- PIPELINE_OK);
+ PIPELINE_OK, "0e89c98da281067d58f8459eca0f35ba");
FFMPEG_TEST_CASE(WEBM_6, "security/117912.webm", DEMUXER_ERROR_COULD_NOT_OPEN,
- DEMUXER_ERROR_COULD_NOT_OPEN);
+ DEMUXER_ERROR_COULD_NOT_OPEN, kNullVideoHash);
-// Flaky, maybe larger issues. All eventually fail in the browser.
+// Flaky under threading, maybe larger issues. Values were set with
+// --video-threads=1 under the hope that they may one day pass with threading.
FFMPEG_TEST_CASE(FLAKY_Cr99652, "security/99652.webm", PIPELINE_OK,
- PIPELINE_ERROR_DECODE);
+ PIPELINE_ERROR_DECODE, "43db203056009b7ff3ac145a3488807a");
FFMPEG_TEST_CASE(FLAKY_Cr100464, "security/100464.webm", PIPELINE_OK,
- PIPELINE_ERROR_DECODE);
+ PIPELINE_OK, "985cff66e292f3064bf853e8943fd8c8");
+FFMPEG_TEST_CASE(FLAKY_OGV_3, "security/smclock_1_0.ogv", PIPELINE_OK,
+ PIPELINE_OK, "6923c1e1c6354d8e00cd57b7b66c9b02");
+FFMPEG_TEST_CASE(FLAKY_OGV_4, "security/smclock.ogv.1.0.ogv",
+ PIPELINE_OK, PIPELINE_OK, "6923c1e1c6354d8e00cd57b7b66c9b02");
+FFMPEG_TEST_CASE(FLAKY_OGV_13, "security/smclocktheora_1_790.ogv",
+ PIPELINE_OK, PIPELINE_OK, "6923c1e1c6354d8e00cd57b7b66c9b02");
+FFMPEG_TEST_CASE(FLAKY_MP4_4, "security/clockh264aac_301350139.mp4",
+ PIPELINE_OK, PIPELINE_OK, "87c110e9d0bbaf7a2d9757dc8e2ce9d7");
+
+// Flaky due to other non-threading related reasons:
FFMPEG_TEST_CASE(FLAKY_Cr111342, "security/111342.ogm", PIPELINE_OK,
- PIPELINE_ERROR_DECODE);
-FFMPEG_TEST_CASE(FLAKY_MP4_3, "security/clockh264aac_300413969.mp4",
- PIPELINE_OK, PIPELINE_ERROR_DECODE);
+ PIPELINE_ERROR_DECODE, "a79faa6f4ccb1734e2143d5d37482448");
FFMPEG_TEST_CASE(FLAKY_OGV_0, "security/big_dims.ogv", PIPELINE_OK,
- PIPELINE_ERROR_DECODE);
-FFMPEG_TEST_CASE(FLAKY_OGV_3, "security/smclock_1_0.ogv", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE);
-FFMPEG_TEST_CASE(FLAKY_OGV_4, "security/smclock.ogv.1.0.ogv",
- PIPELINE_OK, PIPELINE_ERROR_DECODE);
+ PIPELINE_OK, "c5c23c1e0958a4a4756c35d045f94e0e");
FFMPEG_TEST_CASE(FLAKY_OGV_6, "security/smclocktheora_1_10000.ogv",
- PIPELINE_OK, PIPELINE_ERROR_DECODE);
-FFMPEG_TEST_CASE(FLAKY_OGV_13, "security/smclocktheora_1_790.ogv",
- PIPELINE_ERROR_DECODE, PIPELINE_ERROR_DECODE);
+ PIPELINE_OK, PIPELINE_OK, "cdce61e17a8058c6ac5fca92cd3e4a86");
+FFMPEG_TEST_CASE(FLAKY_MP4_3, "security/clockh264aac_300413969.mp4",
+ PIPELINE_OK, PIPELINE_OK, "3781a90401195dfb6ad3e4dbc4888f4f");
// Hangs. http://crbug.com/117038
// FFMPEG_TEST_CASE(WEBM_0, "security/memcpy.webm", PIPELINE_OK, PIPELINE_OK);
@@ -176,6 +205,7 @@ TEST_P(FFmpegRegressionTest, BasicPlayback) {
ASSERT_FALSE(Start(GetTestDataURL(GetParam().filename),
GetParam().init_status));
}
+ ASSERT_EQ(GetVideoHash(), GetParam().md5);
}
} // namespace media
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index e954b9f..d8d5f72 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -127,6 +127,7 @@ TEST_F(PipelineIntegrationTest, BasicPlayback) {
Play();
ASSERT_TRUE(WaitUntilOnEnded());
+ ASSERT_EQ(GetVideoHash(), "923ce08df753797b642df55a46a1dcfb");
}
// TODO(xhwang): Enable this test when AddKey is integrated into pipeline.
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index eeb5cb1..e421963 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -5,6 +5,7 @@
#include "media/filters/pipeline_integration_test_base.h"
#include "base/bind.h"
+#include "base/string_piece.h"
#include "media/base/media_log.h"
#include "media/filters/chunk_demuxer_factory.h"
#include "media/filters/ffmpeg_audio_decoder.h"
@@ -12,7 +13,6 @@
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/filters/file_data_source.h"
#include "media/filters/null_audio_renderer.h"
-#include "media/filters/video_renderer_base.h"
using ::testing::AnyNumber;
@@ -23,7 +23,7 @@ PipelineIntegrationTestBase::PipelineIntegrationTestBase()
pipeline_(new Pipeline(&message_loop_, new MediaLog())),
ended_(false),
pipeline_status_(PIPELINE_OK) {
- EXPECT_CALL(*this, OnVideoRendererPaint()).Times(AnyNumber());
+ base::MD5Init(&md5_context_);
EXPECT_CALL(*this, OnSetOpaque(true)).Times(AnyNumber());
}
@@ -170,13 +170,34 @@ PipelineIntegrationTestBase::CreateFilterCollection(
base::Bind(&MessageLoopFactory::GetMessageLoop,
base::Unretained(message_loop_factory_.get()),
"VideoDecoderThread")));
- collection->AddVideoRenderer(new VideoRendererBase(
+ renderer_ = new VideoRendererBase(
base::Bind(&PipelineIntegrationTestBase::OnVideoRendererPaint,
base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnSetOpaque,
- base::Unretained(this))));
+ base::Unretained(this)),
+ false);
+ collection->AddVideoRenderer(renderer_);
collection->AddAudioRenderer(new NullAudioRenderer());
return collection.Pass();
}
+void PipelineIntegrationTestBase::OnVideoRendererPaint() {
+ scoped_refptr<VideoFrame> frame;
+ renderer_->GetCurrentFrame(&frame);
+ if (frame)
+ base::MD5Update(
+ &md5_context_,
+ base::StringPiece(
+ reinterpret_cast<char*>(frame->data(VideoFrame::kRGBPlane)),
+ (frame->rows(VideoFrame::kRGBPlane) *
+ frame->row_bytes(VideoFrame::kRGBPlane))));
+ renderer_->PutCurrentFrame(frame);
+}
+
+std::string PipelineIntegrationTestBase::GetVideoHash() {
+ base::MD5Digest digest;
+ base::MD5Final(&digest, &md5_context_);
+ return base::MD5DigestToBase16(digest);
+}
+
} // namespace media
diff --git a/media/filters/pipeline_integration_test_base.h b/media/filters/pipeline_integration_test_base.h
index 06e6bf1..dfa231b 100644
--- a/media/filters/pipeline_integration_test_base.h
+++ b/media/filters/pipeline_integration_test_base.h
@@ -6,14 +6,19 @@
#define MEDIA_FILTERS_PIPELINE_INTEGRATION_TEST_BASE_H_
#include "base/message_loop.h"
+#include "base/md5.h"
#include "media/base/filter_collection.h"
#include "media/base/message_loop_factory.h"
#include "media/base/pipeline.h"
#include "media/filters/chunk_demuxer.h"
+#include "media/filters/video_renderer_base.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace media {
+// Empty MD5 hash string. Used to verify videos which have decoded no frames.
+static const char kNullVideoHash[] = "d41d8cd98f00b204e9800998ecf8427e";
+
// Integration tests for Pipeline. Real demuxers, real decoders, and
// base renderer implementations are used to verify pipeline functionality. The
// renderers used in these tests rely heavily on the AudioRendererBase &
@@ -40,10 +45,17 @@ class PipelineIntegrationTestBase {
scoped_ptr<FilterCollection> CreateFilterCollection(
ChunkDemuxerClient* client);
+ // Returns the MD5 hash of all video frames seen. Should only be called once
+ // after playback completes. First time hashes should be generated with
+ // --video-threads=1 to ensure correctness.
+ std::string GetVideoHash();
+
protected:
MessageLoop message_loop_;
+ base::MD5Context md5_context_;
scoped_ptr<MessageLoopFactory> message_loop_factory_;
scoped_refptr<Pipeline> pipeline_;
+ scoped_refptr<VideoRendererBase> renderer_;
bool ended_;
PipelineStatus pipeline_status_;
@@ -55,8 +67,8 @@ class PipelineIntegrationTestBase {
void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time);
scoped_ptr<FilterCollection> CreateFilterCollection(
scoped_ptr<DemuxerFactory> demuxer_factory);
+ void OnVideoRendererPaint();
- MOCK_METHOD0(OnVideoRendererPaint, void());
MOCK_METHOD1(OnSetOpaque, void(bool));
};
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index b4c2568..0ecb586 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -15,13 +15,15 @@
namespace media {
VideoRendererBase::VideoRendererBase(const base::Closure& paint_cb,
- const SetOpaqueCB& set_opaque_cb)
+ const SetOpaqueCB& set_opaque_cb,
+ bool drop_frames)
: frame_available_(&lock_),
state_(kUninitialized),
thread_(base::kNullThreadHandle),
pending_read_(false),
pending_paint_(false),
pending_paint_with_last_available_(false),
+ drop_frames_(drop_frames),
playback_rate_(0),
read_cb_(base::Bind(&VideoRendererBase::FrameReady,
base::Unretained(this))),
@@ -259,6 +261,9 @@ void VideoRendererBase::ThreadMain() {
if (remaining_time.InMicroseconds() > 0)
break;
+ if (!drop_frames_)
+ break;
+
// Frame dropped: read again.
++frames_dropped;
ready_frames_.pop_front();
diff --git a/media/filters/video_renderer_base.h b/media/filters/video_renderer_base.h
index fe69571..13e344a 100644
--- a/media/filters/video_renderer_base.h
+++ b/media/filters/video_renderer_base.h
@@ -37,10 +37,13 @@ class MEDIA_EXPORT VideoRendererBase
// instead post a task to a common/worker thread to handle rendering. Slowing
// down the video thread may result in losing synchronization with audio.
//
+ // Setting |drop_frames_| to true causes the renderer to drop expired frames.
+ //
// TODO(scherkus): pass the VideoFrame* to this callback and remove
// Get/PutCurrentFrame() http://crbug.com/108435
VideoRendererBase(const base::Closure& paint_cb,
- const SetOpaqueCB& set_opaque_cb);
+ const SetOpaqueCB& set_opaque_cb,
+ bool drop_frames);
virtual ~VideoRendererBase();
// Filter implementation.
@@ -179,6 +182,8 @@ class MEDIA_EXPORT VideoRendererBase
bool pending_paint_;
bool pending_paint_with_last_available_;
+ bool drop_frames_;
+
float playback_rate_;
// Filter callbacks.
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
index 30c804b..40e0d6a 100644
--- a/media/filters/video_renderer_base_unittest.cc
+++ b/media/filters/video_renderer_base_unittest.cc
@@ -54,7 +54,8 @@ class VideoRendererBaseTest : public ::testing::Test {
renderer_ = new VideoRendererBase(
base::Bind(&VideoRendererBaseTest::Paint, base::Unretained(this)),
base::Bind(&VideoRendererBaseTest::SetOpaqueCBWasCalled,
- base::Unretained(this)));
+ base::Unretained(this)),
+ true);
renderer_->set_host(&host_);
EXPECT_CALL(*decoder_, natural_size())
diff --git a/media/tools/player_wtl/view.h b/media/tools/player_wtl/view.h
index c4ad454..7519b09 100644
--- a/media/tools/player_wtl/view.h
+++ b/media/tools/player_wtl/view.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -43,10 +43,10 @@ class WtlVideoWindow : public CScrollWindowImpl<WtlVideoWindow> {
view_size_ = 2; // Normal size.
view_rotate_ = media::ROTATE_0;
view_filter_ = media::FILTER_NONE;
- renderer_ = new media::VideoRendererBase(base::Bind(
- &WtlVideoWindow::InvalidateWrapper, base::Unretained(this)),
- base::Bind(
- &WtlVideoWindow::SetOpaque, base::Unretained(this)));
+ renderer_ = new media::VideoRendererBase(
+ base::Bind(&WtlVideoWindow::InvalidateWrapper, base::Unretained(this)),
+ base::Bind(&WtlVideoWindow::SetOpaque, base::Unretained(this)),
+ true);
last_frame_ = NULL;
hbmp_ = NULL;
}
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index 5220fd5..8da75de 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -135,7 +135,8 @@ bool InitPipeline(MessageLoop* message_loop,
// Create our video renderer and save a reference to it for painting.
g_video_renderer = new media::VideoRendererBase(
base::Bind(&Paint, paint_message_loop, paint_cb),
- base::Bind(&SetOpaque));
+ base::Bind(&SetOpaque),
+ true);
collection->AddVideoRenderer(g_video_renderer);
collection->AddAudioRenderer(new media::NullAudioRenderer());
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc
index 84d7766..c988faa 100644
--- a/webkit/media/webmediaplayer_impl.cc
+++ b/webkit/media/webmediaplayer_impl.cc
@@ -149,7 +149,8 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
scoped_refptr<media::VideoRendererBase> video_renderer =
new media::VideoRendererBase(
base::Bind(&WebMediaPlayerProxy::Repaint, proxy_),
- base::Bind(&WebMediaPlayerProxy::SetOpaque, proxy_.get()));
+ base::Bind(&WebMediaPlayerProxy::SetOpaque, proxy_.get()),
+ true);
filter_collection_->AddVideoRenderer(video_renderer);
proxy_->set_frame_provider(video_renderer);