Chromium Code Reviews| 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_recorder/video_track_recorder.h" | 5 #include "content/renderer/media_recorder/video_track_recorder.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 | 45 |
| 46 using media::VideoFrame; | 46 using media::VideoFrame; |
| 47 using media::VideoFrameMetadata; | 47 using media::VideoFrameMetadata; |
| 48 using video_track_recorder::kVEAEncoderMinResolutionWidth; | 48 using video_track_recorder::kVEAEncoderMinResolutionWidth; |
| 49 using video_track_recorder::kVEAEncoderMinResolutionHeight; | 49 using video_track_recorder::kVEAEncoderMinResolutionHeight; |
| 50 | 50 |
| 51 namespace content { | 51 namespace content { |
| 52 | 52 |
| 53 namespace { | 53 namespace { |
| 54 | 54 |
| 55 libyuv::RotationMode MediaVideoRotationToRotationMode( | |
| 56 media::VideoRotation rotation) { | |
| 57 switch (rotation) { | |
| 58 case media::VIDEO_ROTATION_0: | |
| 59 return libyuv::kRotate0; | |
| 60 case media::VIDEO_ROTATION_90: | |
| 61 return libyuv::kRotate90; | |
| 62 case media::VIDEO_ROTATION_180: | |
| 63 return libyuv::kRotate180; | |
| 64 case media::VIDEO_ROTATION_270: | |
| 65 return libyuv::kRotate270; | |
| 66 } | |
|
emircan
2017/04/07 19:50:55
Add "NOTREACHED();". It makes sure that we will be
Chandan
2017/04/10 10:36:15
Done.
| |
| 67 return libyuv::kRotate0; | |
| 68 } | |
| 69 | |
| 55 // HW encoders expect a nonzero bitrate, so |kVEADefaultBitratePerPixel| is used | 70 // HW encoders expect a nonzero bitrate, so |kVEADefaultBitratePerPixel| is used |
| 56 // to estimate bits per second for ~30 fps with ~1/16 compression rate. | 71 // to estimate bits per second for ~30 fps with ~1/16 compression rate. |
| 57 const int kVEADefaultBitratePerPixel = 2; | 72 const int kVEADefaultBitratePerPixel = 2; |
| 58 // Number of output buffers used to copy the encoded data coming from HW | 73 // Number of output buffers used to copy the encoded data coming from HW |
| 59 // encoders. | 74 // encoders. |
| 60 const int kVEAEncoderOutputBufferCount = 4; | 75 const int kVEAEncoderOutputBufferCount = 4; |
| 61 | 76 |
| 62 using CodecId = VideoTrackRecorder::CodecId; | 77 using CodecId = VideoTrackRecorder::CodecId; |
| 63 | 78 |
| 64 static const struct { | 79 static const struct { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 // Send black frames (yuv = {0, 127, 127}). | 311 // Send black frames (yuv = {0, 127, 127}). |
| 297 frame = media::VideoFrame::CreateColorFrame( | 312 frame = media::VideoFrame::CreateColorFrame( |
| 298 video_frame->visible_rect().size(), 0u, 0x80, 0x80, | 313 video_frame->visible_rect().size(), 0u, 0x80, 0x80, |
| 299 video_frame->timestamp()); | 314 video_frame->timestamp()); |
| 300 } else { | 315 } else { |
| 301 // Accelerated decoders produce ARGB/ABGR texture-backed frames (see | 316 // Accelerated decoders produce ARGB/ABGR texture-backed frames (see |
| 302 // https://crbug.com/585242), fetch them using a SkCanvasVideoRenderer. | 317 // https://crbug.com/585242), fetch them using a SkCanvasVideoRenderer. |
| 303 DCHECK(video_frame->HasTextures()); | 318 DCHECK(video_frame->HasTextures()); |
| 304 DCHECK_EQ(media::PIXEL_FORMAT_ARGB, video_frame->format()); | 319 DCHECK_EQ(media::PIXEL_FORMAT_ARGB, video_frame->format()); |
| 305 | 320 |
| 306 frame = media::VideoFrame::CreateFrame( | 321 gfx::Size coded_size = video_frame->coded_size(), |
| 307 media::PIXEL_FORMAT_I420, video_frame->coded_size(), | 322 natural_size = video_frame->natural_size(); |
| 308 video_frame->visible_rect(), video_frame->natural_size(), | 323 gfx::Rect visible_rect = video_frame->visible_rect(); |
|
emircan
2017/04/07 19:50:55
You can do all these calculations based on visible
Chandan
2017/04/10 10:36:15
Done.
| |
| 309 video_frame->timestamp()); | 324 media::VideoRotation video_rotation = media::VIDEO_ROTATION_0; |
| 325 if (video_frame->metadata()->GetRotation( | |
| 326 media::VideoFrameMetadata::ROTATION, &video_rotation)) { | |
|
emircan
2017/04/07 19:50:55
Merge two if statements with &&.
Chandan
2017/04/10 10:36:15
Done.
| |
| 327 if (video_rotation == media::VIDEO_ROTATION_90 || | |
| 328 video_rotation == media::VIDEO_ROTATION_270) { | |
| 329 coded_size.SetSize(coded_size.height(), coded_size.width()); | |
| 330 natural_size.SetSize(natural_size.height(), natural_size.width()); | |
| 331 visible_rect.set_width(visible_rect.height()); | |
| 332 visible_rect.set_height(visible_rect.width()); | |
|
Chandan
2017/04/07 13:21:55
I am not too confident of this change. Please sugg
emircan
2017/04/07 19:50:55
I can totally understand, sorry for my late respon
Chandan
2017/04/10 10:36:15
Thanks!
| |
| 333 } | |
| 334 } | |
| 335 | |
| 336 frame = media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_I420, coded_size, | |
| 337 visible_rect, natural_size, | |
| 338 video_frame->timestamp()); | |
| 310 | 339 |
| 311 const SkImageInfo info = SkImageInfo::MakeN32( | 340 const SkImageInfo info = SkImageInfo::MakeN32( |
| 312 frame->visible_rect().width(), frame->visible_rect().height(), | 341 frame->visible_rect().width(), frame->visible_rect().height(), |
| 313 kOpaque_SkAlphaType); | 342 kOpaque_SkAlphaType); |
| 314 | 343 |
| 315 // Create |surface_| if it doesn't exist or incoming resolution has changed. | 344 // Create |surface_| if it doesn't exist or incoming resolution has changed. |
| 316 if (!canvas_ || canvas_->imageInfo().width() != info.width() || | 345 if (!canvas_ || canvas_->imageInfo().width() != info.width() || |
| 317 canvas_->imageInfo().height() != info.height()) { | 346 canvas_->imageInfo().height() != info.height()) { |
| 318 bitmap_.allocPixels(info); | 347 bitmap_.allocPixels(info); |
| 319 canvas_ = base::MakeUnique<cc::SkiaPaintCanvas>(bitmap_); | 348 canvas_ = base::MakeUnique<cc::SkiaPaintCanvas>(bitmap_); |
| 320 } | 349 } |
| 321 if (!video_renderer_) | 350 if (!video_renderer_) |
| 322 video_renderer_.reset(new media::SkCanvasVideoRenderer); | 351 video_renderer_.reset(new media::SkCanvasVideoRenderer); |
| 323 | 352 |
| 324 DCHECK(context_provider->ContextGL()); | 353 DCHECK(context_provider->ContextGL()); |
| 325 video_renderer_->Copy(video_frame.get(), canvas_.get(), | 354 video_renderer_->Copy(video_frame.get(), canvas_.get(), |
| 326 media::Context3D(context_provider->ContextGL(), | 355 media::Context3D(context_provider->ContextGL(), |
| 327 context_provider->GrContext())); | 356 context_provider->GrContext())); |
| 328 | 357 |
| 329 SkPixmap pixmap; | 358 SkPixmap pixmap; |
| 330 if (!bitmap_.peekPixels(&pixmap)) { | 359 if (!bitmap_.peekPixels(&pixmap)) { |
| 331 DLOG(ERROR) << "Error trying to map PaintSurface's pixels"; | 360 DLOG(ERROR) << "Error trying to map PaintSurface's pixels"; |
| 332 return; | 361 return; |
| 333 } | 362 } |
| 334 // TODO(mcasas): Use the incoming frame's rotation when | 363 |
| 335 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6069 is closed. | 364 libyuv::RotationMode source_rotation = libyuv::kRotate0; |
| 336 const libyuv::RotationMode source_rotation = libyuv::kRotate0; | 365 if (video_rotation != media::VIDEO_ROTATION_0) |
| 366 source_rotation = MediaVideoRotationToRotationMode(video_rotation); | |
| 367 | |
| 337 const uint32 source_pixel_format = | 368 const uint32 source_pixel_format = |
| 338 (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR | 369 (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR |
| 339 : libyuv::FOURCC_ARGB; | 370 : libyuv::FOURCC_ARGB; |
| 340 if (libyuv::ConvertToI420(static_cast<uint8*>(pixmap.writable_addr()), | 371 if (libyuv::ConvertToI420(static_cast<uint8*>(pixmap.writable_addr()), |
| 341 pixmap.getSafeSize(), | 372 pixmap.getSafeSize(), |
| 342 frame->visible_data(media::VideoFrame::kYPlane), | 373 frame->visible_data(media::VideoFrame::kYPlane), |
| 343 frame->stride(media::VideoFrame::kYPlane), | 374 frame->stride(media::VideoFrame::kYPlane), |
| 344 frame->visible_data(media::VideoFrame::kUPlane), | 375 frame->visible_data(media::VideoFrame::kUPlane), |
| 345 frame->stride(media::VideoFrame::kUPlane), | 376 frame->stride(media::VideoFrame::kUPlane), |
| 346 frame->visible_data(media::VideoFrame::kVPlane), | 377 frame->visible_data(media::VideoFrame::kVPlane), |
| 347 frame->stride(media::VideoFrame::kVPlane), | 378 frame->stride(media::VideoFrame::kVPlane), |
| 348 0 /* crop_x */, 0 /* crop_y */, | 379 0 /* crop_x */, 0 /* crop_y */, |
| 349 pixmap.width(), pixmap.height(), | 380 pixmap.width(), pixmap.height(), |
| 350 frame->visible_rect().width(), | 381 frame->visible_rect().width(), |
|
emircan
2017/04/07 19:50:55
Use |old_visible_rect| here as well.
Chandan
2017/04/10 10:36:15
Done.
| |
| 351 frame->visible_rect().height(), | 382 frame->visible_rect().height(), |
| 352 source_rotation, | 383 source_rotation, |
| 353 source_pixel_format) != 0) { | 384 source_pixel_format) != 0) { |
| 354 DLOG(ERROR) << "Error converting frame to I420"; | 385 DLOG(ERROR) << "Error converting frame to I420"; |
| 355 return; | 386 return; |
| 356 } | 387 } |
| 357 } | 388 } |
| 358 | 389 |
| 359 encoding_task_runner_->PostTask( | 390 encoding_task_runner_->PostTask( |
| 360 FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingTaskRunner, this, frame, | 391 FROM_HERE, base::Bind(&Encoder::EncodeOnEncodingTaskRunner, this, frame, |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1365 false /*allow_vea_encoder*/)), | 1396 false /*allow_vea_encoder*/)), |
| 1366 false); | 1397 false); |
| 1367 } | 1398 } |
| 1368 | 1399 |
| 1369 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() { | 1400 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() { |
| 1370 DCHECK(encoder_); | 1401 DCHECK(encoder_); |
| 1371 return encoder_->CanEncodeAlphaChannel(); | 1402 return encoder_->CanEncodeAlphaChannel(); |
| 1372 } | 1403 } |
| 1373 | 1404 |
| 1374 } // namespace content | 1405 } // namespace content |
| OLD | NEW |