| Index: content/renderer/pepper/pepper_media_stream_video_track_host.cc
|
| diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3081625be0e485bed4a666438a9daa45ea87ab1e
|
| --- /dev/null
|
| +++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
|
| @@ -0,0 +1,131 @@
|
| +// 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_media_stream_video_track_host.h"
|
| +
|
| +#include "content/public/renderer/render_thread.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +#include "ppapi/c/ppb_video_frame.h"
|
| +#include "ppapi/host/dispatch_host_message.h"
|
| +#include "ppapi/host/ppapi_host.h"
|
| +#include "ppapi/proxy/host_dispatcher.h"
|
| +#include "ppapi/proxy/ppapi_messages.h"
|
| +#include "ppapi/proxy/resource_message_params.h"
|
| +#include "ppapi/shared_impl/video_frame.h"
|
| +
|
| +using media::VideoFrame;
|
| +using ppapi::host::HostMessageContext;
|
| +using ppapi::host::ReplyMessageContext;
|
| +
|
| +namespace {
|
| +
|
| +PP_VideoFrame_Format ToPpapiFormat(media::VideoFrame::Format format) {
|
| + switch (format) {
|
| + case media::VideoFrame::YV12:
|
| + return PP_VIDEOFRAME_FORMAT_YV12;
|
| + case media::VideoFrame::YV16:
|
| + return PP_VIDEOFRAME_FORMAT_YV16;
|
| + case media::VideoFrame::I420:
|
| + return PP_VIDEOFRAME_FORMAT_I420;
|
| + case media::VideoFrame::YV12A:
|
| + return PP_VIDEOFRAME_FORMAT_YV12A;
|
| + case media::VideoFrame::YV12J:
|
| + return PP_VIDEOFRAME_FORMAT_YV12J;
|
| + default:
|
| + DVLOG(1) << "Unsupported pixel format " << format;
|
| + return PP_VIDEOFRAME_FORMAT_UNKNOWN;
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace content {
|
| +
|
| +PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
|
| + RendererPpapiHost* host,
|
| + PP_Instance instance,
|
| + PP_Resource resource,
|
| + const blink::WebMediaStreamTrack& track)
|
| + : PepperIOStreamHost(host, instance, resource, false),
|
| + track_(track),
|
| + frame_buffer_size_(2),
|
| + frame_format_(VideoFrame::UNKNOWN),
|
| + frame_data_size_(0),
|
| + slot_size_(0) {
|
| + DCHECK(!track_.isNull());
|
| +}
|
| +
|
| +PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() {
|
| + MediaStreamVideoSink::RemoveFromVideoTrack(this, track_);
|
| +}
|
| +
|
| +int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived(
|
| + const IPC::Message& msg,
|
| + HostMessageContext* context) {
|
| + IPC_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg)
|
| + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
|
| + PpapiHostMsg_MediaStreamVideoTrack_StartCapture, OnHostMsgStartCapture)
|
| + IPC_END_MESSAGE_MAP()
|
| + return PepperIOStreamHost::OnResourceMessageReceived(msg, context);
|
| +}
|
| +
|
| +void PepperMediaStreamVideoTrackHost::OnVideoFrame(
|
| + const scoped_refptr<VideoFrame>& frame) {
|
| + DCHECK(frame);
|
| + PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format());
|
| + if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN)
|
| + return;
|
| +
|
| + if (frame_size_ != frame->coded_size() || frame_format_ != frame->format()) {
|
| + frame_size_ = frame->coded_size();
|
| + frame_format_ = frame->format();
|
| + AllocFrameBuffers();
|
| + }
|
| +
|
| + ppapi::VideoFrame* ppframe = NULL;
|
| + if (Lock(reinterpret_cast<void**>(&ppframe), slot_size_) != PP_OK) {
|
| + return;
|
| + }
|
| +
|
| + ppframe->timestamp = frame->GetTimestamp().InSecondsF();
|
| + ppframe->format = ppformat;
|
| + ppframe->size.width = frame->coded_size().width();
|
| + ppframe->size.height = frame->coded_size().height();
|
| + ppframe->data_size = frame_data_size_;
|
| +
|
| + COMPILE_ASSERT(VideoFrame::kYPlane == 0, y_plane_should_be_0);
|
| + COMPILE_ASSERT(VideoFrame::kUPlane == 1, u_plane_should_be_1);
|
| + COMPILE_ASSERT(VideoFrame::kVPlane == 2, v_plane_should_be_2);
|
| +
|
| + uint8_t* dst = ppframe->data;
|
| + for (size_t i = 0; i < VideoFrame::NumPlanes(frame->format()); ++i) {
|
| + const uint8_t* src = frame->data(i);
|
| + const size_t row_bytes = frame->row_bytes(i);
|
| + const size_t src_stride = frame->stride(i);
|
| + for (int j = 0; j < frame->rows(i); ++j) {
|
| + memcpy(dst, src, row_bytes);
|
| + dst += row_bytes;
|
| + src += src_stride;
|
| + }
|
| + }
|
| + Unlock(ppframe);
|
| +}
|
| +
|
| +void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() {
|
| + MediaStreamVideoSink::AddToVideoTrack(this, track_);
|
| +}
|
| +
|
| +int32_t PepperMediaStreamVideoTrackHost::OnHostMsgStartCapture(
|
| + HostMessageContext* context) {
|
| + MediaStreamVideoSink::AddToVideoTrack(this, track_);
|
| + return PP_OK;
|
| +}
|
| +
|
| +void PepperMediaStreamVideoTrackHost::AllocFrameBuffers() {
|
| + frame_data_size_ = VideoFrame::AllocationSize(frame_format_, frame_size_);
|
| + slot_size_ = sizeof(ppapi::VideoFrame) + frame_data_size_;
|
| + InitSharedBufferAndNotifyPlugin(frame_buffer_size_ * slot_size_);
|
| +}
|
| +
|
| +} // namespace content
|
|
|