summaryrefslogtreecommitdiffstats
path: root/chromium/content/renderer/pepper/pepper_video_source_host.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/pepper/pepper_video_source_host.cc')
-rw-r--r--chromium/content/renderer/pepper/pepper_video_source_host.cc106
1 files changed, 59 insertions, 47 deletions
diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.cc b/chromium/content/renderer/pepper/pepper_video_source_host.cc
index 2a8bd935934..d90ed26e8e7 100644
--- a/chromium/content/renderer/pepper/pepper_video_source_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_source_host.cc
@@ -5,7 +5,7 @@
#include "content/renderer/pepper/pepper_video_source_host.h"
#include "base/bind.h"
-#include "base/safe_numerics.h"
+#include "base/numerics/safe_conversions.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/render_thread_impl.h"
@@ -17,8 +17,7 @@
#include "ppapi/shared_impl/scoped_pp_resource.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_image_data_api.h"
-#include "third_party/libjingle/source/talk/media/base/videocommon.h"
-#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/skia/include/core/SkBitmap.h"
using ppapi::host::HostMessageContext;
@@ -29,40 +28,34 @@ namespace content {
PepperVideoSourceHost::FrameReceiver::FrameReceiver(
const base::WeakPtr<PepperVideoSourceHost>& host)
: host_(host),
- main_message_loop_proxy_(base::MessageLoopProxy::current()) {
-}
+ main_message_loop_proxy_(base::MessageLoopProxy::current()) {}
-PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {
-}
+PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {}
bool PepperVideoSourceHost::FrameReceiver::GotFrame(
- cricket::VideoFrame* frame) {
+ const scoped_refptr<media::VideoFrame>& frame) {
// It's not safe to access the host from this thread, so post a task to our
// main thread to transfer the new frame.
main_message_loop_proxy_->PostTask(
- FROM_HERE,
- base::Bind(&FrameReceiver::OnGotFrame,
- this,
- base::Passed(scoped_ptr<cricket::VideoFrame>(frame))));
+ FROM_HERE, base::Bind(&FrameReceiver::OnGotFrame, this, frame));
return true;
}
void PepperVideoSourceHost::FrameReceiver::OnGotFrame(
- scoped_ptr<cricket::VideoFrame> frame) {
+ const scoped_refptr<media::VideoFrame>& frame) {
if (host_.get()) {
- // Take ownership of the new frame, and possibly delete any unsent one.
- host_->last_frame_.swap(frame);
+ // Hold a reference to the new frame and release the previous.
+ host_->last_frame_ = frame;
if (host_->get_frame_pending_)
host_->SendGetFrameReply();
}
}
-PepperVideoSourceHost::PepperVideoSourceHost(
- RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource)
+PepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
source_handler_(new VideoSourceHandler(NULL)),
@@ -71,21 +64,19 @@ PepperVideoSourceHost::PepperVideoSourceHost(
frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr());
}
-PepperVideoSourceHost::~PepperVideoSourceHost() {
- Close();
-}
+PepperVideoSourceHost::~PepperVideoSourceHost() { Close(); }
int32_t PepperVideoSourceHost::OnResourceMessageReceived(
const IPC::Message& msg,
HostMessageContext* context) {
- IPC_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg)
+ PPAPI_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open,
OnHostMsgOpen)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame,
OnHostMsgGetFrame)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close,
OnHostMsgClose)
- IPC_END_MESSAGE_MAP()
+ PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
@@ -132,10 +123,12 @@ void PepperVideoSourceHost::SendGetFrameReply() {
get_frame_pending_ = false;
DCHECK(last_frame_.get());
- scoped_ptr<cricket::VideoFrame> frame(last_frame_.release());
+ scoped_refptr<media::VideoFrame> frame(last_frame_);
+ last_frame_ = NULL;
+
+ const int dst_width = frame->visible_rect().width();
+ const int dst_height = frame->visible_rect().height();
- int32_t width = base::checked_numeric_cast<int32_t>(frame->GetWidth());
- int32_t height = base::checked_numeric_cast<int32_t>(frame->GetHeight());
PP_ImageDataDesc image_desc;
IPC::PlatformFileForTransit image_handle;
uint32_t byte_count;
@@ -145,9 +138,11 @@ void PepperVideoSourceHost::SendGetFrameReply() {
pp_instance(),
ppapi::PPB_ImageData_Shared::SIMPLE,
PP_IMAGEDATAFORMAT_BGRA_PREMUL,
- PP_MakeSize(width, height),
+ PP_MakeSize(dst_width, dst_height),
false /* init_to_zero */,
- &image_desc, &image_handle, &byte_count));
+ &image_desc,
+ &image_handle,
+ &byte_count));
if (!resource.get()) {
SendGetFrameErrorReply(PP_ERROR_FAILED);
return;
@@ -179,30 +174,48 @@ void PepperVideoSourceHost::SendGetFrameReply() {
return;
}
- size_t bitmap_size = bitmap->getSize();
- frame->ConvertToRgbBuffer(cricket::FOURCC_BGRA,
- bitmap_pixels,
- bitmap_size,
- bitmap->rowBytes());
+ // Calculate that portion of the |frame| that should be copied into
+ // |bitmap|. If |frame| has been cropped,
+ // frame->coded_size() != frame->visible_rect().
+ const int src_width = frame->coded_size().width();
+ const int src_height = frame->coded_size().height();
+ DCHECK(src_width >= dst_width && src_height >= dst_height);
+
+ const int horiz_crop = frame->visible_rect().x();
+ const int vert_crop = frame->visible_rect().y();
+
+ const uint8* src_y = frame->data(media::VideoFrame::kYPlane) +
+ (src_width * vert_crop + horiz_crop);
+ const int center = (src_width + 1) / 2;
+ const uint8* src_u = frame->data(media::VideoFrame::kUPlane) +
+ (center * vert_crop + horiz_crop) / 2;
+ const uint8* src_v = frame->data(media::VideoFrame::kVPlane) +
+ (center * vert_crop + horiz_crop) / 2;
+
+ libyuv::I420ToBGRA(src_y,
+ frame->stride(media::VideoFrame::kYPlane),
+ src_u,
+ frame->stride(media::VideoFrame::kUPlane),
+ src_v,
+ frame->stride(media::VideoFrame::kVPlane),
+ bitmap_pixels,
+ bitmap->rowBytes(),
+ dst_width,
+ dst_height);
ppapi::HostResource host_resource;
host_resource.SetHostResource(pp_instance(), resource.get());
- // Convert a video timestamp (int64, in nanoseconds) to a time delta (int64,
- // microseconds) and then to a PP_TimeTicks (a double, in seconds). All times
- // are relative to the Unix Epoch.
- base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
- frame->GetTimeStamp() / base::Time::kNanosecondsPerMicrosecond);
- PP_TimeTicks timestamp = time_delta.InSecondsF();
+ // Convert a video timestamp to a PP_TimeTicks (a double, in seconds).
+ PP_TimeTicks timestamp = frame->timestamp().InSecondsF();
ppapi::proxy::SerializedHandle serialized_handle;
serialized_handle.set_shmem(image_handle, byte_count);
reply_context_.params.AppendHandle(serialized_handle);
host()->SendReply(reply_context_,
- PpapiPluginMsg_VideoSource_GetFrameReply(host_resource,
- image_desc,
- timestamp));
+ PpapiPluginMsg_VideoSource_GetFrameReply(
+ host_resource, image_desc, timestamp));
reply_context_ = ppapi::host::ReplyMessageContext();
@@ -214,15 +227,14 @@ void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) {
reply_context_.params.set_result(error);
host()->SendReply(
reply_context_,
- PpapiPluginMsg_VideoSource_GetFrameReply(ppapi::HostResource(),
- PP_ImageDataDesc(),
- 0.0 /* timestamp */));
+ PpapiPluginMsg_VideoSource_GetFrameReply(
+ ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */));
reply_context_ = ppapi::host::ReplyMessageContext();
}
void PepperVideoSourceHost::Close() {
if (source_handler_.get() && !stream_url_.empty())
- source_handler_->Close(stream_url_, frame_receiver_.get());
+ source_handler_->Close(frame_receiver_.get());
source_handler_.reset(NULL);
stream_url_.clear();