1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/pepper_media_stream_video_track_host.h"
7 #include "base/logging.h"
8 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/c/ppb_video_frame.h"
10 #include "ppapi/shared_impl/media_stream_buffer.h"
12 using media::VideoFrame;
16 // TODO(penghuang): make it configurable.
17 const int32_t kNumberOfFrames = 4;
19 PP_VideoFrame_Format ToPpapiFormat(VideoFrame::Format format) {
21 case VideoFrame::YV12:
22 return PP_VIDEOFRAME_FORMAT_YV12;
23 case VideoFrame::YV16:
24 return PP_VIDEOFRAME_FORMAT_YV16;
25 case VideoFrame::I420:
26 return PP_VIDEOFRAME_FORMAT_I420;
27 case VideoFrame::YV12A:
28 return PP_VIDEOFRAME_FORMAT_YV12A;
29 case VideoFrame::YV12J:
30 return PP_VIDEOFRAME_FORMAT_YV12J;
32 DVLOG(1) << "Unsupported pixel format " << format;
33 return PP_VIDEOFRAME_FORMAT_UNKNOWN;
41 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
42 RendererPpapiHost* host,
45 const blink::WebMediaStreamTrack& track)
46 : PepperMediaStreamTrackHostBase(host, instance, resource),
49 frame_format_(VideoFrame::UNKNOWN),
51 DCHECK(!track_.isNull());
54 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() {
58 void PepperMediaStreamVideoTrackHost::OnClose() {
60 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_);
65 void PepperMediaStreamVideoTrackHost::OnVideoFrame(
66 const scoped_refptr<VideoFrame>& frame) {
68 // TODO(penghuang): Check |frame->end_of_stream()| and close the track.
69 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format());
70 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN)
73 if (frame_size_ != frame->coded_size() || frame_format_ != frame->format()) {
74 frame_size_ = frame->coded_size();
75 frame_format_ = frame->format();
76 // TODO(penghuang): Support changing |frame_size_| & |frame_format_| more
78 DCHECK(!frame_data_size_);
79 frame_data_size_ = VideoFrame::AllocationSize(frame_format_, frame_size_);
80 int32_t size = sizeof(ppapi::MediaStreamBuffer::Video) + frame_data_size_;
81 bool result = InitBuffers(kNumberOfFrames, size);
82 // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin.
86 int32_t index = buffer_manager()->DequeueBuffer();
87 // Drop frames if the underlying buffer is full.
91 // TODO(penghuang): support format conversion and size scaling.
92 ppapi::MediaStreamBuffer::Video* buffer =
93 &(buffer_manager()->GetBufferPointer(index)->video);
94 buffer->header.size = buffer_manager()->buffer_size();
95 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
96 buffer->timestamp = frame->GetTimestamp().InSecondsF();
97 buffer->format = ppformat;
98 buffer->size.width = frame->coded_size().width();
99 buffer->size.height = frame->coded_size().height();
100 buffer->data_size = frame_data_size_;
102 COMPILE_ASSERT(VideoFrame::kYPlane == 0, y_plane_should_be_0);
103 COMPILE_ASSERT(VideoFrame::kUPlane == 1, u_plane_should_be_1);
104 COMPILE_ASSERT(VideoFrame::kVPlane == 2, v_plane_should_be_2);
106 uint8_t* dst = buffer->data;
107 size_t num_planes = VideoFrame::NumPlanes(frame->format());
108 for (size_t i = 0; i < num_planes; ++i) {
109 const uint8_t* src = frame->data(i);
110 const size_t row_bytes = frame->row_bytes(i);
111 const size_t src_stride = frame->stride(i);
112 int rows = frame->rows(i);
113 for (int j = 0; j < rows; ++j) {
114 memcpy(dst, src, row_bytes);
120 SendEnqueueBufferMessageToPlugin(index);
123 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() {
125 MediaStreamVideoSink::AddToVideoTrack(this, track_);
130 } // namespace content