| OLD | NEW | 
|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "content/renderer/media_capture_from_element/html_video_element_capture
     r_source.h" | 5 #include "content/renderer/media_capture_from_element/html_video_element_capture
     r_source.h" | 
| 6 | 6 | 
| 7 #include "base/location.h" | 7 #include "base/location.h" | 
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" | 
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" | 
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" | 
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" | 
| 12 #include "cc/paint/skia_paint_canvas.h" | 12 #include "cc/paint/paint_canvas.h" | 
|  | 13 #include "cc/paint/paint_surface.h" | 
| 13 #include "content/public/renderer/render_thread.h" | 14 #include "content/public/renderer/render_thread.h" | 
| 14 #include "content/renderer/media/media_stream_video_source.h" | 15 #include "content/renderer/media/media_stream_video_source.h" | 
| 15 #include "content/renderer/media/webrtc_uma_histograms.h" | 16 #include "content/renderer/media/webrtc_uma_histograms.h" | 
| 16 #include "media/base/limits.h" | 17 #include "media/base/limits.h" | 
| 17 #include "media/blink/webmediaplayer_impl.h" | 18 #include "media/blink/webmediaplayer_impl.h" | 
| 18 #include "skia/ext/platform_canvas.h" | 19 #include "skia/ext/platform_canvas.h" | 
| 19 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" | 20 #include "third_party/WebKit/public/platform/WebMediaPlayer.h" | 
| 20 #include "third_party/WebKit/public/platform/WebRect.h" | 21 #include "third_party/WebKit/public/platform/WebRect.h" | 
| 21 #include "third_party/WebKit/public/platform/WebSize.h" | 22 #include "third_party/WebKit/public/platform/WebSize.h" | 
| 22 #include "third_party/libyuv/include/libyuv.h" | 23 #include "third_party/libyuv/include/libyuv.h" | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 86            << media::VideoCaptureFormat::ToString(params.requested_format); | 87            << media::VideoCaptureFormat::ToString(params.requested_format); | 
| 87   DCHECK(params.requested_format.IsValid()); | 88   DCHECK(params.requested_format.IsValid()); | 
| 88   DCHECK(thread_checker_.CalledOnValidThread()); | 89   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 89 | 90 | 
| 90   running_callback_ = running_callback; | 91   running_callback_ = running_callback; | 
| 91   if (!web_media_player_ || !web_media_player_->hasVideo()) { | 92   if (!web_media_player_ || !web_media_player_->hasVideo()) { | 
| 92     running_callback_.Run(false); | 93     running_callback_.Run(false); | 
| 93     return; | 94     return; | 
| 94   } | 95   } | 
| 95   const blink::WebSize resolution = web_media_player_->naturalSize(); | 96   const blink::WebSize resolution = web_media_player_->naturalSize(); | 
| 96   if (!bitmap_.tryAllocPixels( | 97   surface_ = cc::PaintSurface::MakeRasterN32Premul(resolution.width, | 
| 97           SkImageInfo::MakeN32Premul(resolution.width, resolution.height))) { | 98                                                    resolution.height); | 
|  | 99   if (!surface_) { | 
| 98     running_callback_.Run(false); | 100     running_callback_.Run(false); | 
| 99     return; | 101     return; | 
| 100   } | 102   } | 
| 101   canvas_ = base::MakeUnique<cc::SkiaPaintCanvas>(bitmap_); |  | 
| 102 | 103 | 
| 103   new_frame_callback_ = new_frame_callback; | 104   new_frame_callback_ = new_frame_callback; | 
| 104   // Force |capture_frame_rate_| to be in between k{Min,Max}FramesPerSecond. | 105   // Force |capture_frame_rate_| to be in between k{Min,Max}FramesPerSecond. | 
| 105   capture_frame_rate_ = | 106   capture_frame_rate_ = | 
| 106       std::max(kMinFramesPerSecond, | 107       std::max(kMinFramesPerSecond, | 
| 107                std::min(static_cast<float>(media::limits::kMaxFramesPerSecond), | 108                std::min(static_cast<float>(media::limits::kMaxFramesPerSecond), | 
| 108                         params.requested_format.frame_rate)); | 109                         params.requested_format.frame_rate)); | 
| 109 | 110 | 
| 110   running_callback_.Run(true); | 111   running_callback_.Run(true); | 
| 111   base::ThreadTaskRunnerHandle::Get()->PostTask( | 112   base::ThreadTaskRunnerHandle::Get()->PostTask( | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 125   DVLOG(3) << __func__; | 126   DVLOG(3) << __func__; | 
| 126   TRACE_EVENT0("video", "HtmlVideoElementCapturerSource::sendNewFrame"); | 127   TRACE_EVENT0("video", "HtmlVideoElementCapturerSource::sendNewFrame"); | 
| 127   DCHECK(thread_checker_.CalledOnValidThread()); | 128   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 128 | 129 | 
| 129   if (!web_media_player_ || new_frame_callback_.is_null()) | 130   if (!web_media_player_ || new_frame_callback_.is_null()) | 
| 130     return; | 131     return; | 
| 131 | 132 | 
| 132   const base::TimeTicks current_time = base::TimeTicks::Now(); | 133   const base::TimeTicks current_time = base::TimeTicks::Now(); | 
| 133   const blink::WebSize resolution = web_media_player_->naturalSize(); | 134   const blink::WebSize resolution = web_media_player_->naturalSize(); | 
| 134 | 135 | 
|  | 136   cc::PaintCanvas* canvas = surface_->getCanvas(); | 
| 135   cc::PaintFlags flags; | 137   cc::PaintFlags flags; | 
| 136   flags.setBlendMode(SkBlendMode::kSrc); | 138   flags.setBlendMode(SkBlendMode::kSrc); | 
| 137   flags.setFilterQuality(kLow_SkFilterQuality); | 139   flags.setFilterQuality(kLow_SkFilterQuality); | 
| 138   web_media_player_->paint( | 140   web_media_player_->paint( | 
| 139       canvas_.get(), blink::WebRect(0, 0, resolution.width, resolution.height), | 141       canvas, blink::WebRect(0, 0, resolution.width, resolution.height), flags); | 
| 140       flags); | 142   DCHECK_NE(kUnknown_SkColorType, canvas->imageInfo().colorType()); | 
| 141   DCHECK_NE(kUnknown_SkColorType, canvas_->imageInfo().colorType()); | 143   DCHECK_EQ(canvas->imageInfo().width(), resolution.width); | 
| 142   DCHECK_EQ(canvas_->imageInfo().width(), resolution.width); | 144   DCHECK_EQ(canvas->imageInfo().height(), resolution.height); | 
| 143   DCHECK_EQ(canvas_->imageInfo().height(), resolution.height); |  | 
| 144 | 145 | 
| 145   DCHECK_NE(kUnknown_SkColorType, bitmap_.colorType()); | 146   SkBitmap bitmap; | 
| 146   DCHECK(!bitmap_.drawsNothing()); | 147   bitmap.setInfo(canvas->imageInfo()); | 
| 147   DCHECK(bitmap_.getPixels()); | 148   canvas->readPixels(&bitmap, 0, 0); | 
| 148   if (bitmap_.colorType() != kN32_SkColorType) { | 149 | 
|  | 150   DCHECK_NE(kUnknown_SkColorType, bitmap.colorType()); | 
|  | 151   DCHECK(!bitmap.drawsNothing()); | 
|  | 152   DCHECK(bitmap.getPixels()); | 
|  | 153   if (bitmap.colorType() != kN32_SkColorType) { | 
| 149     DLOG(ERROR) << "Only supported color type is kN32_SkColorType (ARGB/ABGR)"; | 154     DLOG(ERROR) << "Only supported color type is kN32_SkColorType (ARGB/ABGR)"; | 
| 150     return; | 155     return; | 
| 151   } | 156   } | 
| 152 | 157 | 
| 153   scoped_refptr<media::VideoFrame> frame = frame_pool_.CreateFrame( | 158   scoped_refptr<media::VideoFrame> frame = frame_pool_.CreateFrame( | 
| 154       media::PIXEL_FORMAT_I420, resolution, gfx::Rect(resolution), resolution, | 159       media::PIXEL_FORMAT_I420, resolution, gfx::Rect(resolution), resolution, | 
| 155       base::TimeTicks::Now() - base::TimeTicks()); | 160       base::TimeTicks::Now() - base::TimeTicks()); | 
| 156   DCHECK(frame); | 161   DCHECK(frame); | 
| 157 | 162 | 
| 158   const uint32 source_pixel_format = | 163   const uint32 source_pixel_format = | 
| 159       (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR | 164       (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR | 
| 160                                                    : libyuv::FOURCC_ARGB; | 165                                                    : libyuv::FOURCC_ARGB; | 
| 161 | 166 | 
| 162   if (libyuv::ConvertToI420( | 167   if (libyuv::ConvertToI420(static_cast<uint8*>(bitmap.getPixels()), | 
| 163           static_cast<uint8*>(bitmap_.getPixels()), bitmap_.getSize(), | 168                             bitmap.getSize(), | 
| 164           frame->data(media::VideoFrame::kYPlane), | 169                             frame->data(media::VideoFrame::kYPlane), | 
| 165           frame->stride(media::VideoFrame::kYPlane), | 170                             frame->stride(media::VideoFrame::kYPlane), | 
| 166           frame->data(media::VideoFrame::kUPlane), | 171                             frame->data(media::VideoFrame::kUPlane), | 
| 167           frame->stride(media::VideoFrame::kUPlane), | 172                             frame->stride(media::VideoFrame::kUPlane), | 
| 168           frame->data(media::VideoFrame::kVPlane), | 173                             frame->data(media::VideoFrame::kVPlane), | 
| 169           frame->stride(media::VideoFrame::kVPlane), 0 /* crop_x */, | 174                             frame->stride(media::VideoFrame::kVPlane), | 
| 170           0 /* crop_y */, bitmap_.info().width(), bitmap_.info().height(), | 175                             0 /* crop_x */, | 
| 171           frame->coded_size().width(), frame->coded_size().height(), | 176                             0 /* crop_y */, | 
| 172           libyuv::kRotate0, source_pixel_format) == 0) { | 177                             bitmap.info().width(), | 
|  | 178                             bitmap.info().height(), | 
|  | 179                             frame->coded_size().width(), | 
|  | 180                             frame->coded_size().height(), | 
|  | 181                             libyuv::kRotate0, | 
|  | 182                             source_pixel_format) == 0) { | 
| 173     // Success! | 183     // Success! | 
| 174     io_task_runner_->PostTask( | 184     io_task_runner_->PostTask( | 
| 175         FROM_HERE, base::Bind(new_frame_callback_, frame, current_time)); | 185         FROM_HERE, base::Bind(new_frame_callback_, frame, current_time)); | 
| 176   } | 186   } | 
| 177 | 187 | 
| 178   // Calculate the time in the future where the next frame should be created. | 188   // Calculate the time in the future where the next frame should be created. | 
| 179   const base::TimeDelta frame_interval = | 189   const base::TimeDelta frame_interval = | 
| 180       base::TimeDelta::FromMicroseconds(1E6 / capture_frame_rate_); | 190       base::TimeDelta::FromMicroseconds(1E6 / capture_frame_rate_); | 
| 181   if (next_capture_time_.is_null()) { | 191   if (next_capture_time_.is_null()) { | 
| 182     next_capture_time_ = current_time + frame_interval; | 192     next_capture_time_ = current_time + frame_interval; | 
| 183   } else { | 193   } else { | 
| 184     next_capture_time_ += frame_interval; | 194     next_capture_time_ += frame_interval; | 
| 185     // Don't accumulate any debt if we are lagging behind - just post next frame | 195     // Don't accumulate any debt if we are lagging behind - just post next frame | 
| 186     // immediately and continue as normal. | 196     // immediately and continue as normal. | 
| 187     if (next_capture_time_ < current_time) | 197     if (next_capture_time_ < current_time) | 
| 188       next_capture_time_ = current_time; | 198       next_capture_time_ = current_time; | 
| 189   } | 199   } | 
| 190   // Schedule next capture. | 200   // Schedule next capture. | 
| 191   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 201   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 
| 192       FROM_HERE, base::Bind(&HtmlVideoElementCapturerSource::sendNewFrame, | 202       FROM_HERE, base::Bind(&HtmlVideoElementCapturerSource::sendNewFrame, | 
| 193                             weak_factory_.GetWeakPtr()), | 203                             weak_factory_.GetWeakPtr()), | 
| 194       next_capture_time_ - current_time); | 204       next_capture_time_ - current_time); | 
| 195 } | 205 } | 
| 196 | 206 | 
| 197 }  // namespace content | 207 }  // namespace content | 
| OLD | NEW | 
|---|