blob: 5254374b1b0fbc5d7777af479cfb94dbac5091ca [file] [log] [blame]
// Copyright (c) 2013 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 "content/renderer/pepper/pepper_video_destination_host.h"
#include "base/time/time.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
using ppapi::host::HostMessageContext;
using ppapi::host::ReplyMessageContext;
namespace content {
PepperVideoDestinationHost::PepperVideoDestinationHost(RendererPpapiHost* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
weak_factory_(this) {}
PepperVideoDestinationHost::~PepperVideoDestinationHost() {}
int32_t PepperVideoDestinationHost::OnResourceMessageReceived(
const IPC::Message& msg,
HostMessageContext* context) {
PPAPI_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_Open,
OnHostMsgOpen)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_PutFrame,
OnHostMsgPutFrame)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDestination_Close,
OnHostMsgClose)
PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
int32_t PepperVideoDestinationHost::OnHostMsgOpen(
HostMessageContext* context,
const std::string& stream_url) {
GURL gurl(stream_url);
if (!gurl.is_valid())
return PP_ERROR_BADARGUMENT;
FrameWriterInterface* frame_writer = NULL;
if (!VideoDestinationHandler::Open(
NULL /* registry */, gurl.spec(), &frame_writer))
return PP_ERROR_FAILED;
frame_writer_.reset(frame_writer);
ReplyMessageContext reply_context = context->MakeReplyMessageContext();
reply_context.params.set_result(PP_OK);
host()->SendReply(reply_context, PpapiPluginMsg_VideoDestination_OpenReply());
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperVideoDestinationHost::OnHostMsgPutFrame(
HostMessageContext* context,
const ppapi::HostResource& image_data_resource,
PP_TimeTicks timestamp) {
ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> enter(
image_data_resource.host_resource(), true);
if (enter.failed())
return PP_ERROR_BADRESOURCE;
PPB_ImageData_Impl* image_data_impl =
static_cast<PPB_ImageData_Impl*>(enter.object());
if (!PPB_ImageData_Impl::IsImageDataFormatSupported(
image_data_impl->format()))
return PP_ERROR_BADARGUMENT;
if (!frame_writer_.get())
return PP_ERROR_FAILED;
// Convert PP_TimeTicks (a double, in seconds) to a TimeDelta (int64,
// microseconds) and then to a video timestamp (int64, nanoseconds). All times
// are relative to the Unix Epoch so don't subtract it to get a delta.
base::TimeDelta time_delta =
base::Time::FromDoubleT(timestamp) - base::Time();
int64_t timestamp_ns =
time_delta.InMicroseconds() * base::Time::kNanosecondsPerMicrosecond;
frame_writer_->PutFrame(image_data_impl, timestamp_ns);
return PP_OK;
}
int32_t PepperVideoDestinationHost::OnHostMsgClose(
HostMessageContext* context) {
frame_writer_.reset(NULL);
return PP_OK;
}
} // namespace content