<commit_before>// Copyright (c) 2010 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.

#include "base/scoped_ptr.h"
#include "media/base/data_buffer.h"
#include "media/base/mock_ffmpeg.h"
#include "media/base/mock_task.h"
#include "media/filters/ffmpeg_video_decode_engine.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::ReturnNull;
using ::testing::SetArgumentPointee;
using ::testing::StrictMock;

namespace media {

static const int kWidth = 320;
static const int kHeight = 240;
static const AVRational kTimeBase = { 1, 100 };

ACTION_P(SaveInitializeResult, engine) {
  engine->info_ = arg0;
}

class FFmpegVideoDecodeEngineTest : public testing::Test,
                                    public VideoDecodeEngine::EventHandler {
 protected:
  FFmpegVideoDecodeEngineTest() {
    // Setup FFmpeg structures.
    frame_buffer_.reset(new uint8[kWidth * kHeight]);
    memset(&yuv_frame_, 0, sizeof(yuv_frame_));

    // DecodeFrame will check these pointers as non-NULL value.
    yuv_frame_.data[0] = yuv_frame_.data[1] = yuv_frame_.data[2]
        = frame_buffer_.get();
    yuv_frame_.linesize[0] = kWidth;
    yuv_frame_.linesize[1] = yuv_frame_.linesize[2] = kWidth >> 1;

    memset(&codec_context_, 0, sizeof(codec_context_));
    codec_context_.width = kWidth;
    codec_context_.height = kHeight;
    codec_context_.time_base = kTimeBase;

    memset(&codec_, 0, sizeof(codec_));
    memset(&stream_, 0, sizeof(stream_));
    stream_.codec = &codec_context_;
    stream_.r_frame_rate.num = kTimeBase.den;
    stream_.r_frame_rate.den = kTimeBase.num;

    buffer_ = new DataBuffer(1);

    // Initialize MockFFmpeg.
    MockFFmpeg::set(&mock_ffmpeg_);

    test_engine_ = new FFmpegVideoDecodeEngine();
    test_engine_->SetCodecContextForTest(&codec_context_);

    VideoFrame::CreateFrame(VideoFrame::YV12,
                            kWidth,
                            kHeight,
                            StreamSample::kInvalidTimestamp,
                            StreamSample::kInvalidTimestamp,
                            &video_frame_);
  }

  ~FFmpegVideoDecodeEngineTest() {
    test_engine_ = NULL;
    MockFFmpeg::set(NULL);
  }

  void Initialize() {
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
        .WillOnce(Return(&codec_));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
        .WillOnce(Return(&yuv_frame_));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 3))
        .WillOnce(Return(0));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
        .WillOnce(Return(0));
    EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
        .Times(1);

    config_.codec_ = kCodecH264;
    config_.opaque_context_ = &stream_;
    config_.width_ = kWidth;
    config_.height_ = kHeight;
    EXPECT_CALL(*this, OnInitializeComplete(_))
       .WillOnce(SaveInitializeResult(this));
    test_engine_->Initialize(MessageLoop::current(), this, config_);
    EXPECT_TRUE(info_.success_);
  }

 public:
  MOCK_METHOD1(OnFillBufferCallback,
               void(scoped_refptr<VideoFrame> video_frame));
  MOCK_METHOD1(OnEmptyBufferCallback,
               void(scoped_refptr<Buffer> buffer));
  MOCK_METHOD1(OnInitializeComplete,
               void(const VideoCodecInfo& info));
  MOCK_METHOD0(OnUninitializeComplete, void());
  MOCK_METHOD0(OnFlushComplete, void());
  MOCK_METHOD0(OnSeekComplete, void());
  MOCK_METHOD0(OnError, void());
  MOCK_METHOD1(OnFormatChange, void(VideoStreamInfo stream_info));

  scoped_refptr<VideoFrame> video_frame_;
  VideoCodecConfig config_;
  VideoCodecInfo info_;
 protected:
  scoped_refptr<FFmpegVideoDecodeEngine> test_engine_;
  scoped_array<uint8_t> frame_buffer_;
  StrictMock<MockFFmpeg> mock_ffmpeg_;

  AVFrame yuv_frame_;
  AVCodecContext codec_context_;
  AVStream stream_;
  AVCodec codec_;
  scoped_refptr<DataBuffer> buffer_;

};

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) {
  Initialize();
}

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) {
  // Test avcodec_find_decoder() returning NULL.
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
      .WillOnce(ReturnNull());
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
      .WillOnce(Return(&yuv_frame_));
  EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
      .Times(1);

  config_.codec_ = kCodecH264;
  config_.opaque_context_ = &stream_;
  config_.width_ = kWidth;
  config_.height_ = kHeight;
  EXPECT_CALL(*this, OnInitializeComplete(_))
     .WillOnce(SaveInitializeResult(this));
  test_engine_->Initialize(MessageLoop::current(), this, config_);
  EXPECT_FALSE(info_.success_);
}

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_InitThreadFails) {
  // Test avcodec_thread_init() failing.
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
      .WillOnce(Return(&codec_));
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
      .WillOnce(Return(&yuv_frame_));
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 3))
      .WillOnce(Return(-1));
  EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
      .Times(1);

  config_.codec_ = kCodecH264;
  config_.opaque_context_ = &stream_;
  config_.width_ = kWidth;
  config_.height_ = kHeight;
  EXPECT_CALL(*this, OnInitializeComplete(_))<commit_msg>mock test 3 threads not 2 for media BUG=none TEST=none<commit_after>// Copyright (c) 2010 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.

#include "base/scoped_ptr.h"
#include "media/base/data_buffer.h"
#include "media/base/mock_ffmpeg.h"
#include "media/base/mock_task.h"
#include "media/filters/ffmpeg_video_decode_engine.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::ReturnNull;
using ::testing::SetArgumentPointee;
using ::testing::StrictMock;

namespace media {

static const int kWidth = 320;
static const int kHeight = 240;
static const AVRational kTimeBase = { 1, 100 };

ACTION_P(SaveInitializeResult, engine) {
  engine->info_ = arg0;
}

class FFmpegVideoDecodeEngineTest : public testing::Test,
                                    public VideoDecodeEngine::EventHandler {
 protected:
  FFmpegVideoDecodeEngineTest() {
    // Setup FFmpeg structures.
    frame_buffer_.reset(new uint8[kWidth * kHeight]);
    memset(&yuv_frame_, 0, sizeof(yuv_frame_));

    // DecodeFrame will check these pointers as non-NULL value.
    yuv_frame_.data[0] = yuv_frame_.data[1] = yuv_frame_.data[2]
        = frame_buffer_.get();
    yuv_frame_.linesize[0] = kWidth;
    yuv_frame_.linesize[1] = yuv_frame_.linesize[2] = kWidth >> 1;

    memset(&codec_context_, 0, sizeof(codec_context_));
    codec_context_.width = kWidth;
    codec_context_.height = kHeight;
    codec_context_.time_base = kTimeBase;

    memset(&codec_, 0, sizeof(codec_));
    memset(&stream_, 0, sizeof(stream_));
    stream_.codec = &codec_context_;
    stream_.r_frame_rate.num = kTimeBase.den;
    stream_.r_frame_rate.den = kTimeBase.num;

    buffer_ = new DataBuffer(1);

    // Initialize MockFFmpeg.
    MockFFmpeg::set(&mock_ffmpeg_);

    test_engine_ = new FFmpegVideoDecodeEngine();
    test_engine_->SetCodecContextForTest(&codec_context_);

    VideoFrame::CreateFrame(VideoFrame::YV12,
                            kWidth,
                            kHeight,
                            StreamSample::kInvalidTimestamp,
                            StreamSample::kInvalidTimestamp,
                            &video_frame_);
  }

  ~FFmpegVideoDecodeEngineTest() {
    test_engine_ = NULL;
    MockFFmpeg::set(NULL);
  }

  void Initialize() {
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
        .WillOnce(Return(&codec_));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
        .WillOnce(Return(&yuv_frame_));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
        .WillOnce(Return(0));
    EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
        .WillOnce(Return(0));
    EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
        .Times(1);

    config_.codec_ = kCodecH264;
    config_.opaque_context_ = &stream_;
    config_.width_ = kWidth;
    config_.height_ = kHeight;
    EXPECT_CALL(*this, OnInitializeComplete(_))
       .WillOnce(SaveInitializeResult(this));
    test_engine_->Initialize(MessageLoop::current(), this, config_);
    EXPECT_TRUE(info_.success_);
  }

 public:
  MOCK_METHOD1(OnFillBufferCallback,
               void(scoped_refptr<VideoFrame> video_frame));
  MOCK_METHOD1(OnEmptyBufferCallback,
               void(scoped_refptr<Buffer> buffer));
  MOCK_METHOD1(OnInitializeComplete,
               void(const VideoCodecInfo& info));
  MOCK_METHOD0(OnUninitializeComplete, void());
  MOCK_METHOD0(OnFlushComplete, void());
  MOCK_METHOD0(OnSeekComplete, void());
  MOCK_METHOD0(OnError, void());
  MOCK_METHOD1(OnFormatChange, void(VideoStreamInfo stream_info));

  scoped_refptr<VideoFrame> video_frame_;
  VideoCodecConfig config_;
  VideoCodecInfo info_;
 protected:
  scoped_refptr<FFmpegVideoDecodeEngine> test_engine_;
  scoped_array<uint8_t> frame_buffer_;
  StrictMock<MockFFmpeg> mock_ffmpeg_;

  AVFrame yuv_frame_;
  AVCodecContext codec_context_;
  AVStream stream_;
  AVCodec codec_;
  scoped_refptr<DataBuffer> buffer_;

};

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_Normal) {
  Initialize();
}

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_FindDecoderFails) {
  // Test avcodec_find_decoder() returning NULL.
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
      .WillOnce(ReturnNull());
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
      .WillOnce(Return(&yuv_frame_));
  EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
      .Times(1);

  config_.codec_ = kCodecH264;
  config_.opaque_context_ = &stream_;
  config_.width_ = kWidth;
  config_.height_ = kHeight;
  EXPECT_CALL(*this, OnInitializeComplete(_))
     .WillOnce(SaveInitializeResult(this));
  test_engine_->Initialize(MessageLoop::current(), this, config_);
  EXPECT_FALSE(info_.success_);
}

TEST_F(FFmpegVideoDecodeEngineTest, Initialize_InitThreadFails) {
  // Test avcodec_thread_init() failing.
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
      .WillOnce(Return(&codec_));
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecAllocFrame())
      .WillOnce(Return(&yuv_frame_));
  EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
      .WillOnce(Return(-1));
  EXPECT_CALL(*MockFFmpeg::get(), AVFree(&yuv_frame_))
      .Times(1);

  config_.codec_ = kCodecH264;
  config_.opaque_context_ = &stream_;
  config_.width_ = kWidth;
  config_.height_ = kHeight;
  EXPECT_CALL(*this, OnInitializeComplete(_))
{'fraction_non_alphanumeric': 0.12274624744648725, 'fraction_numerical': 0.010125233146815881, 'mean_word_length': 4.346628679962013, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2008446', 'n_tokens_mistral': 3763, 'n_tokens_neox': 3738, 'n_words': 598}