146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <GLES2/gl2.h>
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/shared_memory.h"
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/message_loop/message_loop.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/c/pp_errors.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/c/ppb_video_decoder.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/locking_resource_releaser.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/plugin_message_filter.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppapi_message_utils.h"
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_test.h"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppb_graphics_3d_proxy.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/video_decoder_constants.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/video_decoder_resource.h"
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/thunk/thunk.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ppapi::proxy::ResourceMessageTestSink;
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ppapi {
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace proxy {
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const PP_Resource kGraphics3D = 7;
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kShmSize = 256;
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const size_t kDecodeBufferSize = 16;
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kDecodeId = 5;
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kTextureId1 = 1;
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kTextureId2 = 2;
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kNumRequestedTextures = 2;
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class MockCompletionCallback {
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback() : called_(false) {}
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool called() { return called_; }
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t result() { return result_; }
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Reset() { called_ = false; }
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  static void Callback(void* user_data, int32_t result) {
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback* that =
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        reinterpret_cast<MockCompletionCallback*>(user_data);
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    that->called_ = true;
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    that->result_ = result;
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool called_;
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t result_;
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class VideoDecoderResourceTest : public PluginProxyTest {
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  VideoDecoderResourceTest()
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : decoder_iface_(thunk::GetPPB_VideoDecoder_0_2_Thunk()) {}
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const PPB_VideoDecoder_0_2* decoder_iface() const { return decoder_iface_; }
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendReply(const ResourceMessageCallParams& params,
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 int32_t result,
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 const IPC::Message& nested_message) {
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceMessageReplyParams reply_params(params.pp_resource(),
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                            params.sequence());
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    reply_params.set_result(result);
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                      nested_message);
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendReplyWithHandle(const ResourceMessageCallParams& params,
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           int32_t result,
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           const IPC::Message& nested_message,
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           const SerializedHandle& handle) {
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceMessageReplyParams reply_params(params.pp_resource(),
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                            params.sequence());
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    reply_params.set_result(result);
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    reply_params.AppendHandle(handle);
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                      nested_message);
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_Resource CreateDecoder() {
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource result = decoder_iface()->Create(pp_instance());
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (result) {
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ProxyAutoLock lock;
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ppapi::Resource* resource =
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          GetGlobals()->GetResourceTracker()->GetResource(result);
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      proxy::VideoDecoderResource* decoder =
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          static_cast<proxy::VideoDecoderResource*>(resource);
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      decoder->SetForTest();
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_Resource CreateGraphics3d() {
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ProxyAutoLock lock;
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    HostResource host_resource;
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    host_resource.SetHostResource(pp_instance(), kGraphics3D);
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<ppapi::proxy::Graphics3D> graphics_3d(
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new ppapi::proxy::Graphics3D(host_resource));
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return graphics_3d->GetReference();
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_Resource CreateAndInitializeDecoder() {
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource decoder = CreateDecoder();
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LockingResourceReleaser graphics3d(CreateGraphics3d());
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback cb;
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result = decoder_iface()->Initialize(
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder,
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        graphics3d.get(),
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_VIDEOPROFILE_H264MAIN,
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PP_HARDWAREACCELERATION_WITHFALLBACK,
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          &cb));
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (result != PP_OK_COMPLETIONPENDING)
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return 0;
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceMessageCallParams params;
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC::Message msg;
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!sink().GetFirstResourceCallMatching(
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            PpapiHostMsg_VideoDecoder_Initialize::ID, &params, &msg))
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return 0;
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().ClearMessages();
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_InitializeReply());
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return decoder;
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t CallDecode(PP_Resource pp_decoder,
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     MockCompletionCallback* cb,
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     const PpapiHostMsg_VideoDecoder_GetShm* expected_shm_msg) {
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Set up a handler in case the resource sends a sync message to create
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // shared memory.
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PpapiPluginMsg_VideoDecoder_GetShmReply shm_msg_reply(kShmSize);
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceSyncCallHandler shm_msg_handler(
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        &sink(), PpapiHostMsg_VideoDecoder_GetShm::ID, PP_OK, shm_msg_reply);
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().AddFilter(&shm_msg_handler);
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::SharedMemory shm;
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (expected_shm_msg) {
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      shm.CreateAnonymous(kShmSize);
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::SharedMemoryHandle shm_handle;
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      shm.ShareToProcess(base::GetCurrentProcessHandle(), &shm_handle);
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      SerializedHandle serialized_handle(shm_handle, kShmSize);
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      shm_msg_handler.set_serialized_handle(&serialized_handle);
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    memset(decode_buffer_, 0x55, kDecodeBufferSize);
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result =
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder_iface()->Decode(pp_decoder,
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                kDecodeId,
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                kDecodeBufferSize,
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                decode_buffer_,
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                PP_MakeOptionalCompletionCallback(
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    &MockCompletionCallback::Callback, cb));
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (expected_shm_msg) {
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      uint32_t shm_id, shm_size, expected_shm_id, expected_shm_size;
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      UnpackMessage<PpapiHostMsg_VideoDecoder_GetShm>(
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          *expected_shm_msg, &expected_shm_id, &expected_shm_size);
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if (shm_msg_handler.last_handled_msg().type() == 0 ||
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          !UnpackMessage<PpapiHostMsg_VideoDecoder_GetShm>(
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              shm_msg_handler.last_handled_msg(), &shm_id, &shm_size) ||
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          shm_id != expected_shm_id ||
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          shm_size != expected_shm_size) {
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // Signal that the expected shm message wasn't sent by failing.
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        result = PP_ERROR_FAILED;
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().RemoveFilter(&shm_msg_handler);
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t CallGetPicture(PP_Resource pp_decoder,
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         PP_VideoPicture* picture,
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         MockCompletionCallback* cb) {
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result =
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder_iface()->GetPicture(pp_decoder,
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    picture,
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    PP_MakeOptionalCompletionCallback(
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                        &MockCompletionCallback::Callback, cb));
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void CallRecyclePicture(PP_Resource pp_decoder,
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          const PP_VideoPicture& picture) {
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    decoder_iface()->RecyclePicture(pp_decoder, &picture);
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t CallFlush(PP_Resource pp_decoder, MockCompletionCallback* cb) {
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result =
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder_iface()->Flush(pp_decoder,
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               PP_MakeOptionalCompletionCallback(
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   &MockCompletionCallback::Callback, cb));
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t CallReset(PP_Resource pp_decoder, MockCompletionCallback* cb) {
20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result =
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder_iface()->Reset(pp_decoder,
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               PP_MakeOptionalCompletionCallback(
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   &MockCompletionCallback::Callback, cb));
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendDecodeReply(const ResourceMessageCallParams& params,
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                       uint32_t shm_id) {
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_DecodeReply(shm_id));
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendPictureReady(const ResourceMessageCallParams& params,
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        uint32_t decode_count,
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        uint32_t texture_id) {
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        params,
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_OK,
22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PpapiPluginMsg_VideoDecoder_PictureReady(decode_count, texture_id));
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendFlushReply(const ResourceMessageCallParams& params) {
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_FlushReply());
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendResetReply(const ResourceMessageCallParams& params) {
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_ResetReply());
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendRequestTextures(const ResourceMessageCallParams& params) {
23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params,
23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              PP_OK,
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              PpapiPluginMsg_VideoDecoder_RequestTextures(
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  kNumRequestedTextures,
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  PP_MakeSize(320, 240),
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  GL_TEXTURE_2D,
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  std::vector<gpu::Mailbox>()));
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_NotifyError(error));
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool CheckDecodeMsg(ResourceMessageCallParams* params,
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      uint32_t* shm_id,
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      uint32_t* size,
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      int32_t* decode_id) {
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC::Message msg;
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!sink().GetFirstResourceCallMatching(
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            PpapiHostMsg_VideoDecoder_Decode::ID, params, &msg))
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return false;
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().ClearMessages();
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return UnpackMessage<PpapiHostMsg_VideoDecoder_Decode>(
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        msg, shm_id, size, decode_id);
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool CheckRecyclePictureMsg(ResourceMessageCallParams* params,
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              uint32_t* texture_id) {
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC::Message msg;
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!sink().GetFirstResourceCallMatching(
26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            PpapiHostMsg_VideoDecoder_RecyclePicture::ID, params, &msg))
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return false;
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().ClearMessages();
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return UnpackMessage<PpapiHostMsg_VideoDecoder_RecyclePicture>(msg,
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                                   texture_id);
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool CheckFlushMsg(ResourceMessageCallParams* params) {
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return CheckMsg(params, PpapiHostMsg_VideoDecoder_Flush::ID);
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool CheckResetMsg(ResourceMessageCallParams* params) {
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return CheckMsg(params, PpapiHostMsg_VideoDecoder_Reset::ID);
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void ClearCallbacks(PP_Resource pp_decoder) {
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceMessageCallParams params;
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback cb;
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Reset to abort Decode and GetPicture callbacks.
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    CallReset(pp_decoder, &cb);
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Initialize params so we can reply to the Reset.
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    CheckResetMsg(&params);
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Run the Reset callback.
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendResetReply(params);
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool CheckMsg(ResourceMessageCallParams* params, int id) {
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC::Message msg;
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!sink().GetFirstResourceCallMatching(id, params, &msg))
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return false;
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().ClearMessages();
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return true;
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const PPB_VideoDecoder_0_2* decoder_iface_;
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  char decode_buffer_[kDecodeBufferSize];
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, Initialize) {
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Initialize with 0 graphics3d_context should fail.
31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LockingResourceReleaser decoder(CreateDecoder());
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback cb;
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result = decoder_iface()->Initialize(
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder.get(),
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        0 /* invalid 3d graphics */,
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_VIDEOPROFILE_H264MAIN,
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PP_HARDWAREACCELERATION_WITHFALLBACK,
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          &cb));
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_ERROR_BADRESOURCE, result);
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Initialize with bad profile value should fail.
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LockingResourceReleaser decoder(CreateDecoder());
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback cb;
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result = decoder_iface()->Initialize(
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder.get(),
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        1 /* non-zero resource */,
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        static_cast<PP_VideoProfile>(-1),
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PP_HARDWAREACCELERATION_WITHFALLBACK,
33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          &cb));
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Initialize with valid graphics3d_context and profile should succeed.
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LockingResourceReleaser decoder(CreateDecoder());
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LockingResourceReleaser graphics3d(CreateGraphics3d());
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockCompletionCallback cb;
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t result = decoder_iface()->Initialize(
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder.get(),
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        graphics3d.get(),
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_VIDEOPROFILE_H264MAIN,
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PP_HARDWAREACCELERATION_WITHFALLBACK,
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          &cb));
34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(decoder_iface()->IsVideoDecoder(decoder.get()));
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Another attempt while pending should fail.
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    result = decoder_iface()->Initialize(
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        decoder.get(),
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        graphics3d.get(),
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_VIDEOPROFILE_H264MAIN,
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        PP_HARDWAREACCELERATION_WITHFALLBACK,
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          &cb));
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_ERROR_INPROGRESS, result);
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Check for host message and send a reply to complete initialization.
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ResourceMessageCallParams params;
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC::Message msg;
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(sink().GetFirstResourceCallMatching(
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        PpapiHostMsg_VideoDecoder_Initialize::ID, &params, &msg));
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    sink().ClearMessages();
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_InitializeReply());
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(cb.called());
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_OK, cb.result());
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, Uninitialized) {
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Operations on uninitialized decoders should fail.
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LockingResourceReleaser decoder(CreateDecoder());
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback uncalled_cb;
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallDecode(decoder.get(), &uncalled_cb, NULL));
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallGetPicture(decoder.get(), NULL, &uncalled_cb));
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallFlush(decoder.get(), &uncalled_cb));
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallReset(decoder.get(), &uncalled_cb));
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// message for GetShm isn't received, causing Decode to fail.
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// http://crbug.com/379260
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, DecodeAndGetPicture) {
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ResourceMessageCallParams params, params2;
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t shm_id;
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t decode_size;
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t decode_id;
40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Call Decode until we have the maximum pending, minus one.
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (uint32_t i = 0; i < kMaximumPendingDecodes - 1; i++) {
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PpapiHostMsg_VideoDecoder_GetShm shm_msg(i, kDecodeBufferSize);
40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &uncalled_cb, &shm_msg));
40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_FALSE(uncalled_cb.called());
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(i, shm_id);
40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(kDecodeBufferSize, decode_size);
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // The resource generates uids internally, starting at 1.
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int32_t uid = i + 1;
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_EQ(uid, decode_id);
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Once we've allocated the maximum number of buffers, we must wait.
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PpapiHostMsg_VideoDecoder_GetShm shm_msg(7U, kDecodeBufferSize);
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallDecode(decoder.get(), &decode_cb, &shm_msg));
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(7U, shm_id);
42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(kDecodeBufferSize, decode_size);
42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Calling Decode when another Decode is pending should fail.
42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_INPROGRESS, CallDecode(decoder.get(), &uncalled_cb, NULL));
42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Free up the first decode buffer.
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendDecodeReply(params, 0U);
42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The decoder should run the pending callback.
42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(decode_cb.called());
42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, decode_cb.result());
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  decode_cb.Reset();
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Now try to get a picture. No picture ready message has been received yet.
43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_VideoPicture picture;
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), &picture, &get_picture_cb));
43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(get_picture_cb.called());
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Calling GetPicture when another GetPicture is pending should fail.
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_INPROGRESS,
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), &picture, &uncalled_cb));
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Send 'request textures' message to initialize textures.
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendRequestTextures(params);
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Send a picture ready message for Decode call 1. The GetPicture callback
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // should complete.
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendPictureReady(params, 1U, kTextureId1);
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(get_picture_cb.called());
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, get_picture_cb.result());
44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(kDecodeId, picture.decode_id);
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  get_picture_cb.Reset();
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Send a picture ready message for Decode call 2. Since there is no pending
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GetPicture call, the picture should be queued.
45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendPictureReady(params, 2U, kTextureId2);
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The next GetPicture should return synchronously.
45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, CallGetPicture(decoder.get(), &picture, &uncalled_cb));
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(kDecodeId, picture.decode_id);
45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// message for GetShm isn't received, causing Decode to fail.
46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// http://crbug.com/379260
46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, RecyclePicture) {
46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ResourceMessageCallParams params;
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Get to a state where we have a picture to recycle.
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PpapiHostMsg_VideoDecoder_GetShm shm_msg(0U, kDecodeBufferSize);
47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &decode_cb, &shm_msg));
47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t shm_id;
47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t decode_size;
47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t decode_id;
47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendDecodeReply(params, 0U);
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Send 'request textures' message to initialize textures.
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendRequestTextures(params);
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Call GetPicture and send 'picture ready' message to get a picture to
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // recycle.
48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_VideoPicture picture;
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), &picture, &get_picture_cb));
48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendPictureReady(params, 0U, kTextureId1);
48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(kTextureId1, picture.texture_id);
48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CallRecyclePicture(decoder.get(), picture);
48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t texture_id;
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(CheckRecyclePictureMsg(&params, &texture_id));
49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(kTextureId1, texture_id);
49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ClearCallbacks(decoder.get());
49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, Flush) {
49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ResourceMessageCallParams params, params2;
50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback flush_cb, get_picture_cb, uncalled_cb;
50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING, CallFlush(decoder.get(), &flush_cb));
50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(flush_cb.called());
50446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(CheckFlushMsg(&params));
50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallDecode(decoder.get(), &uncalled_cb, NULL));
50746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
50846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Plugin can call GetPicture while Flush is pending.
51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), NULL, &get_picture_cb));
51246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(get_picture_cb.called());
51346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
51446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_INPROGRESS, CallFlush(decoder.get(), &uncalled_cb));
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
51646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
51746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, CallReset(decoder.get(), &uncalled_cb));
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Plugin can call RecyclePicture while Flush is pending.
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PP_VideoPicture picture;
52246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  picture.texture_id = kTextureId1;
52346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CallRecyclePicture(decoder.get(), picture);
52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t texture_id;
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(CheckRecyclePictureMsg(&params2, &texture_id));
52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendFlushReply(params);
52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Any pending GetPicture call is aborted.
52946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(get_picture_cb.called());
53046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_ABORTED, get_picture_cb.result());
53146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(flush_cb.called());
53246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, flush_cb.result());
53346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(bbudge) Test Reset when we can run the message loop to get aborted
53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// callbacks to run.
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// message for GetShm isn't received, causing Decode to fail.
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// http://crbug.com/379260
54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(VideoDecoderResourceTest, NotifyError) {
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
54446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ResourceMessageCallParams params;
54546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Call Decode and GetPicture to have some pending requests.
54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PpapiHostMsg_VideoDecoder_GetShm shm_msg(0U, kDecodeBufferSize);
54946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &decode_cb, &shm_msg));
55046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(decode_cb.called());
55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), NULL, &get_picture_cb));
55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(get_picture_cb.called());
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Send the decoder resource an unsolicited notify error message. We first
55646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // need to initialize 'params' so the message is routed to the decoder.
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t shm_id;
55846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t decode_size;
55946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int32_t decode_id;
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SendNotifyError(params, PP_ERROR_RESOURCE_FAILED);
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
56346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Any pending message should be run with the reported error.
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(get_picture_cb.called());
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, get_picture_cb.result());
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
56746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // All further calls return the reported error.
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED,
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallDecode(decoder.get(), &uncalled_cb, NULL));
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
57146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED,
57246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            CallGetPicture(decoder.get(), NULL, &uncalled_cb));
57346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
57446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, CallFlush(decoder.get(), &uncalled_cb));
57546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
57646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, CallReset(decoder.get(), &uncalled_cb));
57746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(uncalled_cb.called());
57846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace proxy
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace ppapi
583