// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/proxy/video_encoder_resource.h"

#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/memory/unsafe_shared_memory_region.h"
#include "base/process/process.h"
#include "base/synchronization/waitable_event.h"
#include "ppapi/c/pp_codecs.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_video_encoder.h"
#include "ppapi/c/ppb_video_frame.h"
#include "ppapi/proxy/locking_resource_releaser.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/ppapi_message_utils.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/shared_impl/media_stream_buffer.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/thunk/thunk.h"

using ppapi::proxy::ResourceMessageTestSink;

namespace ppapi {
namespace proxy {

namespace {

class MockCompletionCallback {
 public:
  MockCompletionCallback()
      : called_(false),
        call_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                    base::WaitableEvent::InitialState::NOT_SIGNALED) {}

  bool called() { return called_; }
  int32_t result() { return result_; }

  void WaitUntilCalled() { call_event_.Wait(); }

  void Reset() {
    called_ = false;
    call_event_.Reset();
  }

  static void Callback(void* user_data, int32_t result) {
    MockCompletionCallback* that =
        reinterpret_cast<MockCompletionCallback*>(user_data);
    that->call_event_.Signal();
    that->called_ = true;
    that->result_ = result;
  }

 private:
  bool called_;
  int32_t result_;
  base::WaitableEvent call_event_;
};

class VideoEncoderResourceTest : public PluginProxyTest,
                                 public MediaStreamBufferManager::Delegate {
 public:
  VideoEncoderResourceTest()
      : encoder_iface_(thunk::GetPPB_VideoEncoder_0_2_Thunk()),
        encoder_iface_0_1_(thunk::GetPPB_VideoEncoder_0_1_Thunk()),
        video_frames_manager_(this) {}
  ~VideoEncoderResourceTest() override {}

  const PPB_VideoEncoder_0_2* encoder_iface() const { return encoder_iface_; }
  const PPB_VideoEncoder_0_1* encoder_iface_0_1() const {
    return encoder_iface_0_1_;
  }

  const uint32_t kBitstreamBufferSize = 4000;
  const uint32_t kBitstreamBufferCount = 5;
  const uint32_t kVideoFrameCount = 3;
  const uint32_t kBitrate = 200000;

  const PP_Size kFrameSize = PP_MakeSize(640, 480);

  void SendReply(const ResourceMessageCallParams& params,
                 int32_t result,
                 const IPC::Message& nested_message) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  void SendReplyWithHandle(const ResourceMessageCallParams& params,
                           int32_t result,
                           const IPC::Message& nested_message,
                           SerializedHandle handle) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    reply_params.AppendHandle(std::move(handle));
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  void SendReplyWithHandles(const ResourceMessageCallParams& params,
                            int32_t result,
                            const IPC::Message& nested_message,
                            std::vector<SerializedHandle> handles) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    for (auto& handle : handles)
      reply_params.AppendHandle(std::move(handle));
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  PP_Resource CreateEncoder() {
    PP_Resource result = encoder_iface()->Create(pp_instance());
    return result;
  }

  void CreateBitstreamSharedMemory(uint32_t buffer_size, uint32_t nb_buffers) {
    shared_memory_bitstreams_.clear();
    for (uint32_t i = 0; i < nb_buffers; ++i) {
      base::UnsafeSharedMemoryRegion region =
          base::UnsafeSharedMemoryRegion::Create(buffer_size);
      ASSERT_TRUE(region.IsValid());
      shared_memory_bitstreams_.push_back(std::move(region));
    }
  }

  void CreateVideoFramesSharedMemory(uint32_t frame_length,
                                     uint32_t frame_count) {
    uint32_t buffer_length =
        frame_length + sizeof(ppapi::MediaStreamBuffer::Video);
    base::UnsafeSharedMemoryRegion shared_memory_frames =
        base::UnsafeSharedMemoryRegion::Create(buffer_length * frame_count);
    ASSERT_TRUE(shared_memory_frames.IsValid());
    ASSERT_TRUE(video_frames_manager_.SetBuffers(
        frame_count, buffer_length, std::move(shared_memory_frames), true));
    for (int32_t i = 0; i < video_frames_manager_.number_of_buffers(); ++i) {
      ppapi::MediaStreamBuffer::Video* buffer =
        &(video_frames_manager_.GetBufferPointer(i)->video);
      buffer->header.size = buffer_length;
      buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
      buffer->format = PP_VIDEOFRAME_FORMAT_I420;
      buffer->size = kFrameSize;
      buffer->data_size = frame_length;
    }
  }

  PP_Resource CreateAndInitializeEncoder() {
    PP_Resource encoder = CreateEncoder();
    PP_Size size = kFrameSize;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder, PP_VIDEOFRAME_FORMAT_I420, &size, PP_VIDEOPROFILE_H264MAIN,
        kBitrate, PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    if (result != PP_OK_COMPLETIONPENDING)
      return 0;
    ResourceMessageCallParams params;
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_Initialize::ID, &params, &msg))
      return 0;
    sink().ClearMessages();

    SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize);
    CreateBitstreamSharedMemory(kBitstreamBufferSize, kBitstreamBufferCount);
    SendBitstreamBuffers(params, kBitstreamBufferSize);

    if (!cb.called() || cb.result() != PP_OK)
      return 0;

    return encoder;
  }

  int32_t CallGetFramesRequired(PP_Resource pp_encoder) {
    return encoder_iface()->GetFramesRequired(pp_encoder);
  }

  int32_t CallGetFrameCodedSize(PP_Resource pp_encoder, PP_Size* coded_size) {
    return encoder_iface()->GetFrameCodedSize(pp_encoder, coded_size);
  }

  int32_t CallGetVideoFrame(PP_Resource pp_encoder,
                            PP_Resource* video_frame,
                            MockCompletionCallback* cb) {
    return encoder_iface()->GetVideoFrame(
        pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
                                     &MockCompletionCallback::Callback, cb));
  }

  int32_t CallFirstGetVideoFrame(PP_Resource pp_encoder,
                                 PP_Resource* video_frame,
                                 MockCompletionCallback* cb) {
    int32_t result = encoder_iface()->GetVideoFrame(
        pp_encoder, video_frame, PP_MakeOptionalCompletionCallback(
                                     &MockCompletionCallback::Callback, cb));
    if (result != PP_OK_COMPLETIONPENDING)
      return result;

    ResourceMessageCallParams params;
    CheckGetVideoFramesMsg(&params);

    uint32_t frame_length = kFrameSize.width * kFrameSize.height * 2;
    CreateVideoFramesSharedMemory(frame_length, kVideoFrameCount);
    SendGetVideoFramesReply(params, kVideoFrameCount, frame_length, kFrameSize);

    return result;
  }

  int32_t CallEncode(PP_Resource pp_encoder,
                     PP_Resource video_frame,
                     PP_Bool force_keyframe,
                     MockCompletionCallback* cb) {
    return encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
                                   PP_MakeOptionalCompletionCallback(
                                       &MockCompletionCallback::Callback, cb));
  }

  int32_t CallCompleteEncode(PP_Resource pp_encoder,
                             PP_Resource video_frame,
                             PP_Bool force_keyframe,
                             MockCompletionCallback* cb) {
    int32_t result =
        encoder_iface()->Encode(pp_encoder, video_frame, force_keyframe,
                                PP_MakeOptionalCompletionCallback(
                                    &MockCompletionCallback::Callback, cb));
    if (result != PP_OK_COMPLETIONPENDING)
      return result;

    ResourceMessageCallParams params;
    uint32_t frame_id;
    bool forced_keyframe;
    if (!CheckEncodeMsg(&params, &frame_id, &forced_keyframe))
      return PP_ERROR_FAILED;

    SendEncodeReply(params, frame_id);

    return result;
  }

  int32_t CallGetBitstreamBuffer(PP_Resource pp_encoder,
                                 PP_BitstreamBuffer* bitstream_buffer,
                                 MockCompletionCallback* cb) {
    return encoder_iface()->GetBitstreamBuffer(
        pp_encoder, bitstream_buffer,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          cb));
  }

  void CallRecycleBitstreamBuffer(PP_Resource pp_encoder,
                                  const PP_BitstreamBuffer& buffer) {
    encoder_iface()->RecycleBitstreamBuffer(pp_encoder, &buffer);
  }

  void CallRequestEncodingParametersChange(PP_Resource pp_encoder,
                                           uint32_t bitrate,
                                           uint32_t framerate) {
    encoder_iface()->RequestEncodingParametersChange(pp_encoder, bitrate,
                                                     framerate);
  }

  void CallClose(PP_Resource pp_encoder) {
    encoder_iface()->Close(pp_encoder);
  }

  void SendGetSupportedProfilesReply(
      const ResourceMessageCallParams& params,
      const std::vector<PP_VideoProfileDescription>& profiles) {
    SendReply(params, PP_OK,
              PpapiPluginMsg_VideoEncoder_GetSupportedProfilesReply(profiles));
  }

  void SendInitializeReply(const ResourceMessageCallParams& params,
                           int32_t success,
                           uint32_t input_frame_count,
                           const PP_Size& input_coded_size) {
    SendReply(params, success, PpapiPluginMsg_VideoEncoder_InitializeReply(
                                   input_frame_count, input_coded_size));
  }

  void SendBitstreamBuffers(const ResourceMessageCallParams& params,
                            uint32_t buffer_length) {
    std::vector<SerializedHandle> handles;
    for (const auto& mem : shared_memory_bitstreams_) {
      ASSERT_EQ(mem.GetSize(), buffer_length);
      base::UnsafeSharedMemoryRegion region = mem.Duplicate();
      ASSERT_TRUE(region.IsValid());
      handles.push_back(SerializedHandle(std::move(region)));
    }
    SendReplyWithHandles(
        params, PP_OK,
        PpapiPluginMsg_VideoEncoder_BitstreamBuffers(buffer_length),
        std::move(handles));
  }

  void SendGetVideoFramesReply(const ResourceMessageCallParams& params,
                               uint32_t frame_count,
                               uint32_t frame_length,
                               const PP_Size& size) {
    base::UnsafeSharedMemoryRegion region =
        video_frames_manager_.region().Duplicate();
    ASSERT_TRUE(region.IsValid());
    SendReplyWithHandle(
        params, PP_OK,
        PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
            frame_count, frame_length + sizeof(MediaStreamBuffer::Video), size),
        SerializedHandle(std::move(region)));
  }

  void SendEncodeReply(const ResourceMessageCallParams& params,
                       uint32_t frame_id) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_EncodeReply(frame_id));
  }

  void SendBitstreamBufferReady(const ResourceMessageCallParams& params,
                                uint32_t buffer_id,
                                uint32_t buffer_size,
                                bool keyframe) {
    SendReply(params, PP_OK,
              PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
                  buffer_id, buffer_size, PP_FromBool(keyframe)));
  }

  void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoEncoder_NotifyError(error));
  }

  bool CheckGetSupportedProfilesMsg(ResourceMessageCallParams* params) {
    IPC::Message msg;
    return sink().GetFirstResourceCallMatching(
        PpapiHostMsg_VideoEncoder_GetSupportedProfiles::ID, params, &msg);
  }

  bool CheckInitializeMsg(ResourceMessageCallParams* params,
                          PP_VideoFrame_Format* input_format,
                          struct PP_Size* input_visible_size,
                          PP_VideoProfile* output_profile,
                          uint32_t* bitrate,
                          PP_HardwareAcceleration* acceleration) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_Initialize::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<PpapiHostMsg_VideoEncoder_Initialize>(
        msg, input_format, input_visible_size, output_profile, bitrate,
        acceleration);
  }

  bool CheckGetVideoFramesMsg(ResourceMessageCallParams* params) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_GetVideoFrames::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return true;
  }

  bool CheckEncodeMsg(ResourceMessageCallParams* params,
                      uint32_t* frame_id,
                      bool* keyframe) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_Encode::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<PpapiHostMsg_VideoEncoder_Encode>(msg, frame_id,
                                                           keyframe);
  }

  bool CheckRecycleBitstreamBufferMsg(ResourceMessageCallParams* params,
                                      uint32_t* buffer_id) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<PpapiHostMsg_VideoEncoder_RecycleBitstreamBuffer>(
        msg, buffer_id);
  }

  bool CheckRequestEncodingParametersChangeMsg(
      ResourceMessageCallParams* params,
      uint32_t* bitrate,
      uint32_t* framerate) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange::ID,
            params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<
        PpapiHostMsg_VideoEncoder_RequestEncodingParametersChange>(msg, bitrate,
                                                                   framerate);
  }

  bool CheckIsVideoFrame(PP_Resource video_frame) {
    return thunk::GetPPB_VideoFrame_0_1_Thunk()->IsVideoFrame(video_frame);
  }

  bool CheckIsVideoFrameValid(PP_Resource video_frame) {
    PP_Size frame_size;
    return thunk::GetPPB_VideoFrame_0_1_Thunk()->GetSize(
               video_frame, &frame_size) == PP_TRUE;
  }

 private:
  // MediaStreamBufferManager::Delegate:
  void OnNewBufferEnqueued() override {}

  const PPB_VideoEncoder_0_2* encoder_iface_;
  const PPB_VideoEncoder_0_1* encoder_iface_0_1_;

  std::vector<base::UnsafeSharedMemoryRegion> shared_memory_bitstreams_;

  MediaStreamBufferManager video_frames_manager_;
};

void* ForwardUserData(void* user_data,
                      uint32_t element_count,
                      uint32_t element_size) {
  return user_data;
}

}  // namespace

TEST_F(VideoEncoderResourceTest, GetSupportedProfiles) {
  // Verifies that GetSupportedProfiles calls into the renderer and
  // the we get the right results back.
  {
    LockingResourceReleaser encoder(CreateEncoder());
    PP_VideoProfileDescription profiles[2];
    PP_ArrayOutput output;
    output.user_data = &profiles[0];
    output.GetDataBuffer = ForwardUserData;
    ResourceMessageCallParams params;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->GetSupportedProfiles(
        encoder.get(), output, PP_MakeOptionalCompletionCallback(
                                   &MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    ASSERT_TRUE(CheckGetSupportedProfilesMsg(&params));

    std::vector<PP_VideoProfileDescription> profiles_response;
    PP_VideoProfileDescription profile;
    profile.profile = PP_VIDEOPROFILE_H264MAIN;
    profile.max_resolution.width = 1920;
    profile.max_resolution.height = 1080;
    profile.max_framerate_numerator = 30;
    profile.max_framerate_denominator = 1;
    profile.hardware_accelerated = PP_TRUE;
    profiles_response.push_back(profile);
    profile.profile = PP_VIDEOPROFILE_VP8_ANY;
    profile.max_resolution.width = 1920;
    profile.max_resolution.height = 1080;
    profile.max_framerate_numerator = 30;
    profile.max_framerate_denominator = 1;
    profile.hardware_accelerated = PP_FALSE;
    profiles_response.push_back(profile);

    SendGetSupportedProfilesReply(params, profiles_response);
    ASSERT_EQ(profiles_response.size(), static_cast<uint32_t>(cb.result()));
    ASSERT_EQ(0, memcmp(&profiles[0], &profiles_response[0], sizeof(profiles)));
  }
}

TEST_F(VideoEncoderResourceTest, GetSupportedProfiles0_1) {
  // Verifies that GetSupportedProfiles calls into the renderer and
  // the we get the right results back.
  {
    LockingResourceReleaser encoder(CreateEncoder());
    PP_VideoProfileDescription_0_1 profiles[2];
    PP_ArrayOutput output;
    output.user_data = &profiles[0];
    output.GetDataBuffer = ForwardUserData;
    ResourceMessageCallParams params;
    MockCompletionCallback cb;
    int32_t result = encoder_iface_0_1()->GetSupportedProfiles(
        encoder.get(), output, PP_MakeOptionalCompletionCallback(
                                   &MockCompletionCallback::Callback, &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    ASSERT_TRUE(CheckGetSupportedProfilesMsg(&params));

    std::vector<PP_VideoProfileDescription> profiles_response;
    PP_VideoProfileDescription profile;
    profile.profile = PP_VIDEOPROFILE_H264MAIN;
    profile.max_resolution.width = 1920;
    profile.max_resolution.height = 1080;
    profile.max_framerate_numerator = 30;
    profile.max_framerate_denominator = 1;
    profile.hardware_accelerated = PP_TRUE;
    profiles_response.push_back(profile);
    profile.profile = PP_VIDEOPROFILE_VP8_ANY;
    profile.max_resolution.width = 1920;
    profile.max_resolution.height = 1080;
    profile.max_framerate_numerator = 30;
    profile.max_framerate_denominator = 1;
    profile.hardware_accelerated = PP_FALSE;
    profiles_response.push_back(profile);

    SendGetSupportedProfilesReply(params, profiles_response);

    ASSERT_EQ(profiles_response.size(), static_cast<uint32_t>(cb.result()));

    for (uint32_t i = 0; i < profiles_response.size(); i++) {
      ASSERT_EQ(profiles_response[i].profile, profiles[i].profile);
      ASSERT_EQ(profiles_response[i].max_resolution.width,
                profiles[i].max_resolution.width);
      ASSERT_EQ(profiles_response[i].max_resolution.height,
                profiles[i].max_resolution.height);
      ASSERT_EQ(profiles_response[i].max_framerate_numerator,
                profiles[i].max_framerate_numerator);
      ASSERT_EQ(profiles_response[i].max_framerate_denominator,
                profiles[i].max_framerate_denominator);
      if (profiles_response[i].hardware_accelerated)
        ASSERT_EQ(PP_HARDWAREACCELERATION_ONLY, profiles[i].acceleration);
      else
        ASSERT_EQ(PP_HARDWAREACCELERATION_NONE, profiles[i].acceleration);
    }
  }
}

TEST_F(VideoEncoderResourceTest, InitializeFailure) {
  {
    // Verify the initialize callback is called in case of failure.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
    ASSERT_EQ(size.width, input_visible_size.width);
    ASSERT_EQ(size.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    SendInitializeReply(params, PP_ERROR_NOTSUPPORTED, kVideoFrameCount,
                        kFrameSize);
    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_ERROR_NOTSUPPORTED, cb.result());
  }
  {
    // Verify the initialize callback is called in case of error
    // notification.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
    ASSERT_EQ(kFrameSize.width, input_visible_size.width);
    ASSERT_EQ(kFrameSize.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    ResourceMessageCallParams error_params(encoder.get(), 0);
    SendNotifyError(error_params, PP_ERROR_FAILED);
    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, cb.result());
  }
  {
    // Verify that calling initialize twice fails the second time if
    // we haven't received a response yet.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_BGRA, input_format);
    ASSERT_EQ(size.width, input_visible_size.width);
    ASSERT_EQ(size.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_BGRA, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_ERROR_INPROGRESS, result);

    ResourceMessageCallParams error_params(encoder.get(), 0);
    SendNotifyError(error_params, PP_ERROR_FAILED);
    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, cb.result());
  }
}

TEST_F(VideoEncoderResourceTest, InitializeSuccess) {
  {
    // Verify the initialize callback is called when initialization is
    // successful.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    const uint32_t kBitrate = 420000;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
    ASSERT_EQ(kFrameSize.width, input_visible_size.width);
    ASSERT_EQ(kFrameSize.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_OK, cb.result());
  }
  {
    // Verify that calling initialize a second time, after it already
    // succeeded, fails.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    const uint32_t kBitrate = 420000;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
    ASSERT_EQ(kFrameSize.width, input_visible_size.width);
    ASSERT_EQ(kFrameSize.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_OK, cb.result());

    result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_ERROR_FAILED, result);
  }
  {
    // Verify the sending the bitstream buffers details makes them
    // available through the API. the right values.
    LockingResourceReleaser encoder(CreateEncoder());
    ResourceMessageCallParams params;
    PP_Size size = kFrameSize;
    const uint32_t kBitrate = 420000;
    MockCompletionCallback cb;
    int32_t result = encoder_iface()->Initialize(
        encoder.get(), PP_VIDEOFRAME_FORMAT_I420, &size,
        PP_VIDEOPROFILE_H264MAIN, kBitrate,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);

    PP_VideoFrame_Format input_format;
    PP_Size input_visible_size;
    PP_VideoProfile output_profile;
    uint32_t bitrate;
    PP_HardwareAcceleration acceleration;
    ASSERT_TRUE(CheckInitializeMsg(&params, &input_format, &input_visible_size,
                                   &output_profile, &bitrate, &acceleration));
    ASSERT_EQ(PP_VIDEOFRAME_FORMAT_I420, input_format);
    ASSERT_EQ(kFrameSize.width, input_visible_size.width);
    ASSERT_EQ(kFrameSize.height, input_visible_size.height);
    ASSERT_EQ(kBitrate, bitrate);
    ASSERT_EQ(PP_VIDEOPROFILE_H264MAIN, output_profile);
    ASSERT_EQ(PP_HARDWAREACCELERATION_WITHFALLBACK, acceleration);

    SendInitializeReply(params, PP_OK, kVideoFrameCount, kFrameSize);

    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_OK, cb.result());

    PP_Size coded_size;
    ASSERT_EQ(PP_OK, CallGetFrameCodedSize(encoder.get(), &coded_size));
    ASSERT_EQ(kFrameSize.width, coded_size.width);
    ASSERT_EQ(kFrameSize.height, coded_size.height);
    ASSERT_EQ(static_cast<int32_t>(kVideoFrameCount),
              CallGetFramesRequired(encoder.get()));
  }
}

TEST_F(VideoEncoderResourceTest, Uninitialized) {
  // Operations on uninitialized encoders should fail.
  LockingResourceReleaser encoder(CreateEncoder());

  ASSERT_EQ(PP_ERROR_FAILED, CallGetFramesRequired(encoder.get()));

  PP_Size size;
  ASSERT_EQ(PP_ERROR_FAILED, CallGetFrameCodedSize(encoder.get(), &size));

  MockCompletionCallback uncalled_cb;
  PP_Resource video_frame = 0;
  ASSERT_EQ(PP_ERROR_FAILED,
            CallGetVideoFrame(encoder.get(), &video_frame, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
  ASSERT_EQ(0, video_frame);

  ASSERT_EQ(PP_ERROR_FAILED,
            CallEncode(encoder.get(), video_frame, PP_FALSE, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  PP_BitstreamBuffer bitstream_buffer;
  ASSERT_EQ(
      PP_ERROR_FAILED,
      CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  ResourceMessageCallParams params;
  uint32_t buffer_id;
  CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);
  ASSERT_FALSE(CheckRecycleBitstreamBufferMsg(&params, &buffer_id));

  uint32_t bitrate, framerate;
  CallRequestEncodingParametersChange(encoder.get(), 0, 0);
  ASSERT_FALSE(
      CheckRequestEncodingParametersChangeMsg(&params, &bitrate, &framerate));
}

TEST_F(VideoEncoderResourceTest, InitializeAndGetVideoFrame) {
  // Verify that we can pull the right number of video frames before
  // the proxy makes us wait.
  LockingResourceReleaser encoder(CreateAndInitializeEncoder());
  ResourceMessageCallParams params;
  std::vector<PP_Resource> video_frames;
  MockCompletionCallback get_frame_cb;

  video_frames.resize(kVideoFrameCount + 1);

  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetVideoFrame(encoder.get(), &video_frames[0], &get_frame_cb));
  ASSERT_FALSE(get_frame_cb.called());
  ASSERT_TRUE(CheckGetVideoFramesMsg(&params));

  uint32_t frame_length = kFrameSize.width * kFrameSize.height * 2;
  CreateVideoFramesSharedMemory(frame_length, kVideoFrameCount);
  SendGetVideoFramesReply(params, kVideoFrameCount, frame_length, kFrameSize);

  for (uint32_t i = 1; i < kVideoFrameCount; ++i) {
    get_frame_cb.Reset();
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallGetVideoFrame(encoder.get(), &video_frames[i], &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());
    ASSERT_TRUE(CheckIsVideoFrame(video_frames[i]));
  }

  get_frame_cb.Reset();
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameCount],
                              &get_frame_cb));
  ASSERT_FALSE(get_frame_cb.called());

  MockCompletionCallback get_frame_fail_cb;
  ASSERT_EQ(PP_ERROR_INPROGRESS,
            CallGetVideoFrame(encoder.get(), &video_frames[kVideoFrameCount],
                              &get_frame_fail_cb));
  ASSERT_FALSE(get_frame_fail_cb.called());

  // Unblock the GetVideoFrame callback by freeing up a frame.
  MockCompletionCallback encode_cb;
  ASSERT_EQ(
      PP_OK_COMPLETIONPENDING,
      CallCompleteEncode(encoder.get(), video_frames[0], PP_FALSE, &encode_cb));
  ASSERT_TRUE(encode_cb.called());
  ASSERT_EQ(PP_OK, encode_cb.result());
  ASSERT_TRUE(get_frame_cb.called());

  CallClose(encoder.get());
}

TEST_F(VideoEncoderResourceTest, Encode) {
  // Check Encode() calls into the renderer.
  LockingResourceReleaser encoder(CreateAndInitializeEncoder());
  PP_Resource video_frame;
  MockCompletionCallback get_frame_cb;

  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
  ASSERT_TRUE(get_frame_cb.called());
  ASSERT_EQ(PP_OK, get_frame_cb.result());

  MockCompletionCallback encode_cb;
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallEncode(encoder.get(), video_frame, PP_TRUE, &encode_cb));
  ASSERT_FALSE(encode_cb.called());
  ASSERT_FALSE(CheckIsVideoFrameValid(video_frame));

  ResourceMessageCallParams params;
  uint32_t frame_id;
  bool force_frame;
  ASSERT_TRUE(CheckEncodeMsg(&params, &frame_id, &force_frame));

  SendEncodeReply(params, frame_id);

  ASSERT_TRUE(encode_cb.called());
  ASSERT_EQ(PP_OK, encode_cb.result());
}

TEST_F(VideoEncoderResourceTest, EncodeAndGetVideoFrame) {
  // Check the encoding loop works well.
  LockingResourceReleaser encoder(CreateAndInitializeEncoder());
  ResourceMessageCallParams params;
  PP_Resource video_frame;
  MockCompletionCallback get_frame_cb, encode_cb;

  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallFirstGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
  ASSERT_TRUE(get_frame_cb.called());
  ASSERT_EQ(PP_OK, get_frame_cb.result());

  for (uint32_t i = 1; i < 20 * kVideoFrameCount; ++i) {
    encode_cb.Reset();
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
    ASSERT_TRUE(encode_cb.called());
    ASSERT_EQ(PP_OK, encode_cb.result());

    get_frame_cb.Reset();
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());
    ASSERT_TRUE(CheckIsVideoFrame(video_frame));
  }

  ASSERT_EQ(
      PP_OK_COMPLETIONPENDING,
      CallCompleteEncode(encoder.get(), video_frame, PP_FALSE, &encode_cb));
  ASSERT_TRUE(encode_cb.called());
  ASSERT_EQ(PP_OK, encode_cb.result());
}

TEST_F(VideoEncoderResourceTest, GetBitstreamBuffer) {
  {
    // Verify that the GetBitstreamBuffer callback is fired whenever the
    // renderer signals a buffer is available.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));
    ASSERT_FALSE(get_bitstream_buffer_cb.called());

    ResourceMessageCallParams buffer_params(encoder.get(), 0);
    SendBitstreamBufferReady(buffer_params, 0, 10, true);

    ASSERT_TRUE(get_bitstream_buffer_cb.called());
    ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());
    ASSERT_EQ(10U, bitstream_buffer.size);
    ASSERT_EQ(PP_TRUE, bitstream_buffer.key_frame);
  }
  {
    // Verify that calling GetBitstreamBuffer a second time, while the
    // first callback hasn't been fired fails.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));
    ASSERT_FALSE(get_bitstream_buffer_cb.called());

    ASSERT_EQ(PP_ERROR_INPROGRESS,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));
    ASSERT_FALSE(get_bitstream_buffer_cb.called());

    ResourceMessageCallParams buffer_params(encoder.get(), 0);
    SendBitstreamBufferReady(buffer_params, 0, 10, true);
  }
}

TEST_F(VideoEncoderResourceTest, RecycleBitstreamBuffer) {
  // Verify that we signal the renderer that a bitstream buffer has been
  // recycled.
  LockingResourceReleaser encoder(CreateAndInitializeEncoder());

  MockCompletionCallback get_bitstream_buffer_cb;
  PP_BitstreamBuffer bitstream_buffer;
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                   &get_bitstream_buffer_cb));
  ASSERT_FALSE(get_bitstream_buffer_cb.called());

  ResourceMessageCallParams buffer_params(encoder.get(), 0);
  SendBitstreamBufferReady(buffer_params, kBitstreamBufferCount - 1, 10, true);

  ASSERT_TRUE(get_bitstream_buffer_cb.called());
  ASSERT_EQ(PP_OK, get_bitstream_buffer_cb.result());

  CallRecycleBitstreamBuffer(encoder.get(), bitstream_buffer);

  ResourceMessageCallParams recycle_params;
  uint32_t buffer_id;
  ASSERT_TRUE(CheckRecycleBitstreamBufferMsg(&recycle_params, &buffer_id));
  ASSERT_EQ(kBitstreamBufferCount - 1, buffer_id);
}

TEST_F(VideoEncoderResourceTest, RequestEncodingParametersChange) {
  // Check encoding parameter changes are correctly sent to the
  // renderer.
  LockingResourceReleaser encoder(CreateAndInitializeEncoder());

  CallRequestEncodingParametersChange(encoder.get(), 1, 2);
  ResourceMessageCallParams params;
  uint32_t bitrate, framerate;
  ASSERT_TRUE(
      CheckRequestEncodingParametersChangeMsg(&params, &bitrate, &framerate));
  ASSERT_EQ(1U, bitrate);
  ASSERT_EQ(2U, framerate);
}

TEST_F(VideoEncoderResourceTest, NotifyError) {
  {
    // Check an error from the encoder aborts GetVideoFrame and
    // GetBitstreamBuffer callbacks.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_frame_cb;
    PP_Resource video_frame;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
    ASSERT_FALSE(get_frame_cb.called());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));

    ResourceMessageCallParams error_params(encoder.get(), 0);
    SendNotifyError(error_params, PP_ERROR_FAILED);

    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, get_frame_cb.result());
    ASSERT_TRUE(get_bitstream_buffer_cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
  }
  {
    // Check an error from the encoder aborts Encode and GetBitstreamBuffer
    // callbacks.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2;
    PP_Resource video_frame1, video_frame2;
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());

    get_frame_cb.Reset();
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallFirstGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());

    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1));
    ASSERT_FALSE(encode_cb1.called());
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2));
    ASSERT_FALSE(encode_cb2.called());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));

    ResourceMessageCallParams error_params(encoder.get(), 0);
    SendNotifyError(error_params, PP_ERROR_FAILED);

    ASSERT_TRUE(encode_cb1.called());
    ASSERT_EQ(PP_ERROR_FAILED, encode_cb1.result());
    ASSERT_TRUE(encode_cb2.called());
    ASSERT_EQ(PP_ERROR_FAILED, encode_cb2.result());
    ASSERT_TRUE(get_bitstream_buffer_cb.called());
    ASSERT_EQ(PP_ERROR_FAILED, get_bitstream_buffer_cb.result());
  }
}

TEST_F(VideoEncoderResourceTest, Close) {
  {
    // Check closing the encoder aborts GetVideoFrame and
    // GetBitstreamBuffer callbacks.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_frame_cb;
    PP_Resource video_frame;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetVideoFrame(encoder.get(), &video_frame, &get_frame_cb));
    ASSERT_FALSE(get_frame_cb.called());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));

    CallClose(encoder.get());

    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_ERROR_ABORTED, get_frame_cb.result());
    ASSERT_TRUE(get_bitstream_buffer_cb.called());
    ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result());
  }
  {
    // Check closing the encoder aborts Encode and GetBitstreamBuffer
    // callbacks.
    LockingResourceReleaser encoder(CreateAndInitializeEncoder());

    MockCompletionCallback get_frame_cb, encode_cb1, encode_cb2;
    PP_Resource video_frame1, video_frame2;
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallFirstGetVideoFrame(encoder.get(), &video_frame1, &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());

    get_frame_cb.Reset();
    ASSERT_EQ(
        PP_OK_COMPLETIONPENDING,
        CallFirstGetVideoFrame(encoder.get(), &video_frame2, &get_frame_cb));
    ASSERT_TRUE(get_frame_cb.called());
    ASSERT_EQ(PP_OK, get_frame_cb.result());

    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallEncode(encoder.get(), video_frame1, PP_FALSE, &encode_cb1));
    ASSERT_FALSE(encode_cb1.called());
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallEncode(encoder.get(), video_frame2, PP_FALSE, &encode_cb2));
    ASSERT_FALSE(encode_cb2.called());

    MockCompletionCallback get_bitstream_buffer_cb;
    PP_BitstreamBuffer bitstream_buffer;
    ASSERT_EQ(PP_OK_COMPLETIONPENDING,
              CallGetBitstreamBuffer(encoder.get(), &bitstream_buffer,
                                     &get_bitstream_buffer_cb));

    CallClose(encoder.get());

    ASSERT_TRUE(encode_cb1.called());
    ASSERT_EQ(PP_ERROR_ABORTED, encode_cb1.result());
    ASSERT_TRUE(encode_cb2.called());
    ASSERT_EQ(PP_ERROR_ABORTED, encode_cb2.result());
    ASSERT_TRUE(get_bitstream_buffer_cb.called());
    ASSERT_EQ(PP_ERROR_ABORTED, get_bitstream_buffer_cb.result());

    // Verify that a remaining encode response from the renderer is
    // discarded.
    ResourceMessageCallParams params;
    uint32_t frame_id;
    bool force_frame;
    ASSERT_TRUE(CheckEncodeMsg(&params, &frame_id, &force_frame));
    SendEncodeReply(params, frame_id);
  }
}

}  // namespace proxy
}  // namespace ppapi
