Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: content/renderer/media/rtc_video_encoder.cc

Issue 1128213005: Passing Native Texture backed Video Frame from Renderer to GPU process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: posciak@ and magjed@ comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/rtc_video_encoder.h" 5 #include "content/renderer/media/rtc_video_encoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_vector.h" 10 #include "base/memory/scoped_vector.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "base/thread_task_runner_handle.h" 15 #include "base/thread_task_runner_handle.h"
16 #include "media/base/bind_to_current_loop.h"
16 #include "media/base/bitstream_buffer.h" 17 #include "media/base/bitstream_buffer.h"
17 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
18 #include "media/base/video_util.h" 19 #include "media/base/video_util.h"
19 #include "media/filters/h264_parser.h" 20 #include "media/filters/h264_parser.h"
20 #include "media/renderers/gpu_video_accelerator_factories.h" 21 #include "media/renderers/gpu_video_accelerator_factories.h"
21 #include "media/video/video_encode_accelerator.h" 22 #include "media/video/video_encode_accelerator.h"
22 #include "third_party/libyuv/include/libyuv.h" 23 #include "third_party/libyuv/include/libyuv.h"
23 #include "third_party/webrtc/system_wrappers/interface/tick_util.h" 24 #include "third_party/webrtc/system_wrappers/interface/tick_util.h"
24 25
25 #define NOTIFY_ERROR(x) \ 26 #define NOTIFY_ERROR(x) \
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 bool next_frame_keyframe = input_next_frame_keyframe_; 485 bool next_frame_keyframe = input_next_frame_keyframe_;
485 input_next_frame_ = NULL; 486 input_next_frame_ = NULL;
486 input_next_frame_keyframe_ = false; 487 input_next_frame_keyframe_ = false;
487 488
488 if (!video_encoder_) { 489 if (!video_encoder_) {
489 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR); 490 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR);
490 return; 491 return;
491 } 492 }
492 493
493 const int index = input_buffers_free_.back(); 494 const int index = input_buffers_free_.back();
494 base::SharedMemory* input_buffer = input_buffers_[index]; 495
495 scoped_refptr<media::VideoFrame> frame = 496 if (next_frame->native_handle()) {
496 media::VideoFrame::WrapExternalSharedMemory( 497 scoped_refptr<media::VideoFrame> frame(
497 media::VideoFrame::I420, 498 static_cast<media::VideoFrame*>(next_frame->native_handle()));
498 input_frame_coded_size_, 499 frame->AddDestructionObserver(media::BindToCurrentLoop(
499 gfx::Rect(input_visible_size_), 500 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)));
500 input_visible_size_, 501 video_encoder_->Encode(frame, next_frame_keyframe);
501 reinterpret_cast<uint8*>(input_buffer->memory()), 502 } else {
502 input_buffer->mapped_size(), 503 base::SharedMemory* input_buffer = input_buffers_[index];
503 input_buffer->handle(), 504 scoped_refptr<media::VideoFrame> frame =
504 0, 505 media::VideoFrame::WrapExternalSharedMemory(
505 base::TimeDelta()); 506 media::VideoFrame::I420, input_frame_coded_size_,
506 frame->AddDestructionObserver( 507 gfx::Rect(input_visible_size_), input_visible_size_,
507 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)); 508 reinterpret_cast<uint8*>(input_buffer->memory()),
508 if (!frame.get()) { 509 input_buffer->mapped_size(), input_buffer->handle(), 0,
509 DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame"; 510 base::TimeDelta());
510 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); 511 frame->AddDestructionObserver(
mcasas 2015/06/04 15:20:56 Could we move the frame->AddDestructionObserver()
511 return; 512 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index));
513 if (!frame.get()) {
514 DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame";
515 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
516 return;
517 }
518
519 // Do a strided copy of the input frame to match the input requirements for
520 // the encoder.
521 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
522 if (libyuv::I420Copy(next_frame->buffer(webrtc::kYPlane),
523 next_frame->stride(webrtc::kYPlane),
524 next_frame->buffer(webrtc::kUPlane),
525 next_frame->stride(webrtc::kUPlane),
526 next_frame->buffer(webrtc::kVPlane),
527 next_frame->stride(webrtc::kVPlane),
528 frame->data(media::VideoFrame::kYPlane),
529 frame->stride(media::VideoFrame::kYPlane),
530 frame->data(media::VideoFrame::kUPlane),
531 frame->stride(media::VideoFrame::kUPlane),
532 frame->data(media::VideoFrame::kVPlane),
533 frame->stride(media::VideoFrame::kVPlane),
534 next_frame->width(), next_frame->height())) {
535 DLOG(ERROR) << "Failed to copy buffer";
536 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
537 return;
538 }
539 video_encoder_->Encode(frame, next_frame_keyframe);
512 } 540 }
513 541
514 // Do a strided copy of the input frame to match the input requirements for
515 // the encoder.
516 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
517 if (libyuv::I420Copy(next_frame->buffer(webrtc::kYPlane),
518 next_frame->stride(webrtc::kYPlane),
519 next_frame->buffer(webrtc::kUPlane),
520 next_frame->stride(webrtc::kUPlane),
521 next_frame->buffer(webrtc::kVPlane),
522 next_frame->stride(webrtc::kVPlane),
523 frame->data(media::VideoFrame::kYPlane),
524 frame->stride(media::VideoFrame::kYPlane),
525 frame->data(media::VideoFrame::kUPlane),
526 frame->stride(media::VideoFrame::kUPlane),
527 frame->data(media::VideoFrame::kVPlane),
528 frame->stride(media::VideoFrame::kVPlane),
529 next_frame->width(),
530 next_frame->height())) {
531 DLOG(ERROR) << "Failed to copy buffer";
532 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
533 return;
534 }
535
536 video_encoder_->Encode(frame, next_frame_keyframe);
537 input_buffers_free_.pop_back(); 542 input_buffers_free_.pop_back();
538 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); 543 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK);
539 } 544 }
540 545
541 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) { 546 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) {
542 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index; 547 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index;
543 DCHECK(thread_checker_.CalledOnValidThread()); 548 DCHECK(thread_checker_.CalledOnValidThread());
544 DCHECK_GE(index, 0); 549 DCHECK_GE(index, 0);
545 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); 550 DCHECK_LT(index, static_cast<int>(input_buffers_.size()));
546 input_buffers_free_.push_back(index); 551 input_buffers_free_.push_back(index);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", 784 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess",
780 init_retval == WEBRTC_VIDEO_CODEC_OK); 785 init_retval == WEBRTC_VIDEO_CODEC_OK);
781 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { 786 if (init_retval == WEBRTC_VIDEO_CODEC_OK) {
782 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", 787 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile",
783 profile, 788 profile,
784 media::VIDEO_CODEC_PROFILE_MAX + 1); 789 media::VIDEO_CODEC_PROFILE_MAX + 1);
785 } 790 }
786 } 791 }
787 792
788 } // namespace content 793 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698