Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Unified Diff: media/filters/ffmpeg_video_decoder_unittest.cc

Issue 297553002: Add callback in VideoDecoder and AudioDecoder to return decoded frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_video_decoder_unittest.cc
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index 24627f2874bd2677b36b86eff17e73b857f98d91..e64b6df4d1b6b5755d86c4565ba06a318368d9f0 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <list>
#include <string>
#include <vector>
@@ -26,6 +27,7 @@
using ::testing::_;
using ::testing::AtLeast;
+using ::testing::AtMost;
using ::testing::InSequence;
using ::testing::IsNull;
using ::testing::Return;
@@ -47,7 +49,7 @@ class FFmpegVideoDecoderTest : public testing::Test {
public:
FFmpegVideoDecoderTest()
: decoder_(new FFmpegVideoDecoder(message_loop_.message_loop_proxy())),
- decode_cb_(base::Bind(&FFmpegVideoDecoderTest::FrameReady,
+ decode_cb_(base::Bind(&FFmpegVideoDecoderTest::DecodeDone,
base::Unretained(this))) {
FFmpegGlue::InitializeFFmpeg();
@@ -68,7 +70,9 @@ class FFmpegVideoDecoderTest : public testing::Test {
void InitializeWithConfigAndStatus(const VideoDecoderConfig& config,
PipelineStatus status) {
- decoder_->Initialize(config, false, NewExpectedStatusCB(status));
+ decoder_->Initialize(config, false, NewExpectedStatusCB(status),
+ base::Bind(&FFmpegVideoDecoderTest::FrameReady,
+ base::Unretained(this)));
message_loop_.RunUntilIdle();
}
@@ -93,24 +97,18 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Sets up expectations and actions to put FFmpegVideoDecoder in an active
// decoding state.
void EnterDecodingState() {
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> video_frame;
- DecodeSingleFrame(i_frame_buffer_, &status, &video_frame);
-
- EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_TRUE(video_frame.get());
- EXPECT_FALSE(video_frame->end_of_stream());
+ EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_));
+ ASSERT_EQ(2U, output_frames_.size());
+ EXPECT_FALSE(output_frames_[0]->end_of_stream());
+ EXPECT_TRUE(output_frames_[1]->end_of_stream());
}
// Sets up expectations and actions to put FFmpegVideoDecoder in an end
// of stream state.
void EnterEndOfStreamState() {
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> video_frame;
- DecodeSingleFrame(end_of_stream_buffer_, &status, &video_frame);
- EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_TRUE(video_frame.get());
- EXPECT_TRUE(video_frame->end_of_stream());
+ EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(end_of_stream_buffer_));
+ ASSERT_FALSE(output_frames_.empty());
+ EXPECT_TRUE(output_frames_.back()->end_of_stream());
}
typedef std::vector<scoped_refptr<DecoderBuffer> > InputBuffers;
@@ -119,11 +117,10 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Decodes all buffers in |input_buffers| and push all successfully decoded
// output frames (excluding EOS frames) into |output_frames|.
// Returns the last decode status returned by the decoder.
- VideoDecoder::Status DecodeMultipleFrames(const InputBuffers& input_buffers,
- OutputFrames* output_frames) {
+ VideoDecoder::Status DecodeMultipleFrames(const InputBuffers& input_buffers) {
InputBuffers::const_iterator input_iter = input_buffers.begin();
- for (;;) {
+ while (output_frames_.empty() || !output_frames_.back()->end_of_stream()) {
// Prepare input buffer.
scoped_refptr<DecoderBuffer> buffer;
if (input_iter != input_buffers.end()) {
@@ -133,53 +130,33 @@ class FFmpegVideoDecoderTest : public testing::Test {
buffer = end_of_stream_buffer_;
}
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> frame;
- Decode(buffer, &status, &frame);
+ VideoDecoder::Status status = Decode(buffer);
switch (status) {
case VideoDecoder::kOk:
- DCHECK(frame);
- if (!frame->end_of_stream()) {
- output_frames->push_back(frame);
- continue;
- } else { // EOS
- return status;
- }
- case VideoDecoder::kNotEnoughData:
- DCHECK(!frame);
- continue;
+ break;
case VideoDecoder::kAborted:
NOTREACHED();
case VideoDecoder::kDecodeError:
case VideoDecoder::kDecryptError:
- DCHECK(!frame);
+ DCHECK(output_frames_.empty());
return status;
}
}
+
+ return VideoDecoder::kOk;
}
// Decodes the single compressed frame in |buffer| and writes the
// uncompressed output to |video_frame|. This method works with single
// and multithreaded decoders. End of stream buffers are used to trigger
// the frame to be returned in the multithreaded decoder case.
- void DecodeSingleFrame(const scoped_refptr<DecoderBuffer>& buffer,
- VideoDecoder::Status* status,
- scoped_refptr<VideoFrame>* video_frame) {
+ VideoDecoder::Status DecodeSingleFrame(
+ const scoped_refptr<DecoderBuffer>& buffer) {
InputBuffers input_buffers;
input_buffers.push_back(buffer);
- OutputFrames output_frames;
- *status = DecodeMultipleFrames(input_buffers, &output_frames);
-
- if (*status != VideoDecoder::kOk)
- return;
-
- ASSERT_LE(output_frames.size(), 1U);
- if (output_frames.size() == 1U)
- *video_frame = output_frames[0];
- else
- *video_frame = VideoFrame::CreateEOSFrame();
+ return DecodeMultipleFrames(input_buffers);
}
// Decodes |i_frame_buffer_| and then decodes the data contained in
@@ -195,37 +172,40 @@ class FFmpegVideoDecoderTest : public testing::Test {
input_buffers.push_back(i_frame_buffer_);
input_buffers.push_back(buffer);
- OutputFrames output_frames;
VideoDecoder::Status status =
- DecodeMultipleFrames(input_buffers, &output_frames);
+ DecodeMultipleFrames(input_buffers);
EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_EQ(2U, output_frames.size());
+ ASSERT_EQ(3U, output_frames_.size());
gfx::Size original_size = kVisibleRect.size();
EXPECT_EQ(original_size.width(),
- output_frames[0]->visible_rect().size().width());
+ output_frames_[0]->visible_rect().size().width());
EXPECT_EQ(original_size.height(),
- output_frames[0]->visible_rect().size().height());
+ output_frames_[0]->visible_rect().size().height());
EXPECT_EQ(expected_width,
- output_frames[1]->visible_rect().size().width());
+ output_frames_[1]->visible_rect().size().width());
EXPECT_EQ(expected_height,
- output_frames[1]->visible_rect().size().height());
+ output_frames_[1]->visible_rect().size().height());
+ EXPECT_TRUE(output_frames_[2]->end_of_stream());
}
- void Decode(const scoped_refptr<DecoderBuffer>& buffer,
- VideoDecoder::Status* status,
- scoped_refptr<VideoFrame>* video_frame) {
- EXPECT_CALL(*this, FrameReady(_, _))
- .WillOnce(DoAll(SaveArg<0>(status), SaveArg<1>(video_frame)));
+ VideoDecoder::Status Decode(const scoped_refptr<DecoderBuffer>& buffer) {
+ VideoDecoder::Status status;
+ EXPECT_CALL(*this, DecodeDone(_)).WillOnce(SaveArg<0>(&status));
decoder_->Decode(buffer, decode_cb_);
message_loop_.RunUntilIdle();
+
+ return status;
+ }
+
+ void FrameReady(const scoped_refptr<VideoFrame>& frame) {
+ output_frames_.push_back(frame);
}
- MOCK_METHOD2(FrameReady, void(VideoDecoder::Status,
- const scoped_refptr<VideoFrame>&));
+ MOCK_METHOD1(DecodeDone, void(VideoDecoder::Status));
base::MessageLoop message_loop_;
scoped_ptr<FFmpegVideoDecoder> decoder_;
@@ -238,6 +218,8 @@ class FFmpegVideoDecoderTest : public testing::Test {
scoped_refptr<DecoderBuffer> i_frame_buffer_;
scoped_refptr<DecoderBuffer> corrupt_i_frame_buffer_;
+ OutputFrames output_frames_;
+
private:
DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecoderTest);
};
@@ -355,13 +337,10 @@ TEST_F(FFmpegVideoDecoderTest, DecodeFrame_Normal) {
Initialize();
// Simulate decoding a single frame.
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> video_frame;
- DecodeSingleFrame(i_frame_buffer_, &status, &video_frame);
-
- EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_TRUE(video_frame.get());
- EXPECT_FALSE(video_frame->end_of_stream());
+ EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(i_frame_buffer_));
+ ASSERT_EQ(2U, output_frames_.size());
+ EXPECT_FALSE(output_frames_[0]->end_of_stream());
+ EXPECT_TRUE(output_frames_[1]->end_of_stream());
}
// Verify current behavior for 0 byte frames. FFmpeg simply ignores
@@ -376,38 +355,31 @@ TEST_F(FFmpegVideoDecoderTest, DecodeFrame_0ByteFrame) {
input_buffers.push_back(zero_byte_buffer);
input_buffers.push_back(i_frame_buffer_);
- OutputFrames output_frames;
- VideoDecoder::Status status =
- DecodeMultipleFrames(input_buffers, &output_frames);
+ VideoDecoder::Status status = DecodeMultipleFrames(input_buffers);
EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_EQ(2U, output_frames.size());
+ ASSERT_EQ(3U, output_frames_.size());
- EXPECT_FALSE(output_frames[0]->end_of_stream());
- EXPECT_FALSE(output_frames[1]->end_of_stream());
+ EXPECT_FALSE(output_frames_[0]->end_of_stream());
+ EXPECT_FALSE(output_frames_[1]->end_of_stream());
+ EXPECT_TRUE(output_frames_[2]->end_of_stream());
}
TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
Initialize();
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> frame;
-
// The error is only raised on the second decode attempt, so we expect at
// least one successful decode but we don't expect valid frame to be decoded.
// During the second decode attempt an error is raised.
- Decode(corrupt_i_frame_buffer_, &status, &frame);
- DCHECK(!frame);
- DCHECK_EQ(VideoDecoder::kNotEnoughData, status);
- Decode(i_frame_buffer_, &status, &frame);
- DCHECK(!frame);
- DCHECK_EQ(VideoDecoder::kDecodeError, status);
+ EXPECT_EQ(VideoDecoder::kOk, Decode(corrupt_i_frame_buffer_));
+ EXPECT_TRUE(output_frames_.empty());
+ EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_));
+ EXPECT_TRUE(output_frames_.empty());
// After a decode error occurred, all following decodes will return
// kDecodeError.
- Decode(i_frame_buffer_, &status, &frame);
- DCHECK(!frame);
- DCHECK_EQ(VideoDecoder::kDecodeError, status);
+ EXPECT_EQ(VideoDecoder::kDecodeError, Decode(i_frame_buffer_));
+ EXPECT_TRUE(output_frames_.empty());
}
// Multi-threaded decoders have different behavior than single-threaded
@@ -418,13 +390,9 @@ TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeError) {
TEST_F(FFmpegVideoDecoderTest, DecodeFrame_DecodeErrorAtEndOfStream) {
Initialize();
- VideoDecoder::Status status;
- scoped_refptr<VideoFrame> video_frame;
- DecodeSingleFrame(corrupt_i_frame_buffer_, &status, &video_frame);
-
- EXPECT_EQ(VideoDecoder::kOk, status);
- ASSERT_TRUE(video_frame.get());
- EXPECT_TRUE(video_frame->end_of_stream());
+ EXPECT_EQ(VideoDecoder::kOk, DecodeSingleFrame(corrupt_i_frame_buffer_));
+ ASSERT_FALSE(output_frames_.empty());
+ EXPECT_TRUE(output_frames_.back()->end_of_stream());
}
// Decode |i_frame_buffer_| and then a frame with a larger width and verify
« no previous file with comments | « media/filters/ffmpeg_video_decoder.cc ('k') | media/filters/gpu_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698