// Copyright 2015 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 "ppapi/proxy/video_encoder_resource.h"

#include <stdint.h>

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

#include "base/memory/shared_memory.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,
                           const SerializedHandle& handle) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    reply_params.AppendHandle(handle);
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  void SendReplyWithHandles(const ResourceMessageCallParams& params,
                            int32_t result,
                            const IPC::Message& nested_message,
                            const std::vector<SerializedHandle>& handles) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    for (SerializedHandle handle : handles)
      reply_params.AppendHandle(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) {
      std::unique_ptr<base::SharedMemory> mem(new base::SharedMemory());
      ASSERT_TRUE(mem->CreateAnonymous(buffer_size));
      shared_memory_bitstreams_.push_back(std::move(mem));
    }
  }

  void CreateVideoFramesSharedMemory(uint32_t frame_length,
                                     uint32_t frame_count) {
    std::unique_ptr<base::SharedMemory> shared_memory_frames(
        new base::SharedMemory());
    uint32_t buffer_length =
        frame_length + sizeof(ppapi::MediaStreamBuffer::Video);
    ASSERT_TRUE(shared_memory_frames->CreateAnonymous(buffer_length *
                                                      frame_count));
    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->requested_size(), buffer_length);
      base::SharedMemoryHandle handle = mem->handle().Duplicate();
      ASSERT_TRUE(handle.IsValid());
      handles.push_back(SerializedHandle(handle, buffer_length));
    }
    SendReplyWithHandles(
        params, PP_OK,
        PpapiPluginMsg_VideoEncoder_BitstreamBuffers(buffer_length), handles);
  }

  void SendGetVideoFramesReply(const ResourceMessageCallParams& params,
                               uint32_t frame_count,
                               uint32_t frame_length,
                               const PP_Size& size) {
    base::SharedMemoryHandle handle =
        video_frames_manager_.shm()->handle().Duplicate();
    ASSERT_TRUE(handle.IsValid());
    SendReplyWithHandle(
        params, PP_OK, PpapiPluginMsg_VideoEncoder_GetVideoFramesReply(
                           frame_count,
                           frame_length + sizeof(MediaStreamBuffer::Video),
                           size),
        SerializedHandle(
            handle,
            static_cast<uint32_t>(
                video_frames_manager_.shm()->requested_size())));
  }

  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<std::unique_ptr<base::SharedMemory>> 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
