| 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..8e33439d1d6b36f28c1c8d6c2fb37ec18c34796e
|
| --- /dev/null
|
| +++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
|
| @@ -0,0 +1,122 @@
|
| +// Copyright (c) 2014 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 "ppapi/c/pp_errors.h"
|
| +#include "ppapi/c/ppb_video_frame.h"
|
| +#include "ppapi/shared_impl/media_stream_frame.h"
|
| +
|
| +using media::VideoFrame;
|
| +
|
| +namespace {
|
| +
|
| +// TODO(penghuang): make it configurable.
|
| +const int32_t kNumberOfFrames = 4;
|
| +
|
| +PP_VideoFrame_Format ToPpapiFormat(VideoFrame::Format format) {
|
| + switch (format) {
|
| + case VideoFrame::YV12:
|
| + return PP_VIDEOFRAME_FORMAT_YV12;
|
| + case VideoFrame::YV16:
|
| + return PP_VIDEOFRAME_FORMAT_YV16;
|
| + case VideoFrame::I420:
|
| + return PP_VIDEOFRAME_FORMAT_I420;
|
| + case VideoFrame::YV12A:
|
| + return PP_VIDEOFRAME_FORMAT_YV12A;
|
| + case 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)
|
| + : PepperMediaStreamTrackHostBase(host, instance, resource),
|
| + track_(track),
|
| + connected_(false),
|
| + frame_format_(VideoFrame::UNKNOWN),
|
| + frame_data_size_(0) {
|
| + DCHECK(!track_.isNull());
|
| +}
|
| +
|
| +PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() {
|
| + OnClose();
|
| +}
|
| +
|
| +void PepperMediaStreamVideoTrackHost::OnClose() {
|
| + if (connected_) {
|
| + MediaStreamVideoSink::RemoveFromVideoTrack(this, track_);
|
| + connected_ = false;
|
| + }
|
| +}
|
| +
|
| +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();
|
| + // TODO(penghuang): Support changing |frame_size_| & |frame_format_| more
|
| + // than once.
|
| + DCHECK(!frame_data_size_);
|
| + frame_data_size_ = VideoFrame::AllocationSize(frame_format_, frame_size_);
|
| + int32_t size = sizeof(ppapi::MediaStreamFrame::Video) + frame_data_size_;
|
| + InitFrames(kNumberOfFrames, size);
|
| + }
|
| +
|
| + int32_t index = frame_buffer()->DequeueFrame();
|
| + // Drop frames if the underlying buffer is empty.
|
| + if (index < 0)
|
| + return;
|
| +
|
| + ppapi::MediaStreamFrame::Video* ppframe =
|
| + &(frame_buffer()->GetFramePointer(index)->video);
|
| + ppframe->header.size = frame_buffer()->frame_size();
|
| + ppframe->header.type = ppapi::MediaStreamFrame::TYPE_VIDEO;
|
| + 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;
|
| + }
|
| + }
|
| + PluginEnqueueFrame(index);
|
| +}
|
| +
|
| +void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() {
|
| + if (!connected_) {
|
| + MediaStreamVideoSink::AddToVideoTrack(this, track_);
|
| + connected_ = true;
|
| + }
|
| +}
|
| +
|
| +} // namespace content
|
|
|