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

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: Passing a Texture+SharedMemory video frame. 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 scoped_refptr<media::VideoFrame> frame;
495 scoped_refptr<media::VideoFrame> frame = 496 if (next_frame->native_handle()) {
496 media::VideoFrame::WrapExternalSharedMemory( 497 frame = static_cast<media::VideoFrame*>(next_frame->native_handle());
497 media::VideoFrame::I420, 498 } else {
498 input_frame_coded_size_, 499 base::SharedMemory* input_buffer = input_buffers_[index];
499 gfx::Rect(input_visible_size_), 500 frame = media::VideoFrame::WrapExternalSharedMemory(
500 input_visible_size_, 501 media::VideoFrame::I420,
501 reinterpret_cast<uint8*>(input_buffer->memory()), 502 input_frame_coded_size_,
502 input_buffer->mapped_size(), 503 gfx::Rect(input_visible_size_),
503 input_buffer->handle(), 504 input_visible_size_,
504 0, 505 reinterpret_cast<uint8*>(input_buffer->memory()),
505 base::TimeDelta()); 506 input_buffer->mapped_size(),
506 frame->AddDestructionObserver( 507 input_buffer->handle(),
507 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)); 508 0,
508 if (!frame.get()) { 509 base::TimeDelta());
509 DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame"; 510 frame->AddDestructionObserver(
510 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); 511 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index));
511 return; 512 if (!frame.get()) {
513 DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame";
514 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
515 return;
516 }
517 // Do a strided copy of the input frame to match the input requirements for
518 // the encoder.
519 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
520 if (libyuv::I420Copy(next_frame->buffer(webrtc::kYPlane),
521 next_frame->stride(webrtc::kYPlane),
522 next_frame->buffer(webrtc::kUPlane),
523 next_frame->stride(webrtc::kUPlane),
524 next_frame->buffer(webrtc::kVPlane),
525 next_frame->stride(webrtc::kVPlane),
526 frame->data(media::VideoFrame::kYPlane),
527 frame->stride(media::VideoFrame::kYPlane),
528 frame->data(media::VideoFrame::kUPlane),
529 frame->stride(media::VideoFrame::kUPlane),
530 frame->data(media::VideoFrame::kVPlane),
531 frame->stride(media::VideoFrame::kVPlane),
532 next_frame->width(), next_frame->height())) {
533 DLOG(ERROR) << "Failed to copy buffer";
534 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
535 return;
536 }
512 } 537 }
513 538 frame->AddDestructionObserver(media::BindToCurrentLoop(
514 // Do a strided copy of the input frame to match the input requirements for 539 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)));
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); 540 video_encoder_->Encode(frame, next_frame_keyframe);
537 input_buffers_free_.pop_back(); 541 input_buffers_free_.pop_back();
538 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); 542 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK);
539 } 543 }
540 544
541 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) { 545 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) {
542 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index; 546 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index;
543 DCHECK(thread_checker_.CalledOnValidThread()); 547 DCHECK(thread_checker_.CalledOnValidThread());
544 DCHECK_GE(index, 0); 548 DCHECK_GE(index, 0);
545 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); 549 DCHECK_LT(index, static_cast<int>(input_buffers_.size()));
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", 783 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess",
780 init_retval == WEBRTC_VIDEO_CODEC_OK); 784 init_retval == WEBRTC_VIDEO_CODEC_OK);
781 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { 785 if (init_retval == WEBRTC_VIDEO_CODEC_OK) {
782 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", 786 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile",
783 profile, 787 profile,
784 media::VIDEO_CODEC_PROFILE_MAX + 1); 788 media::VIDEO_CODEC_PROFILE_MAX + 1);
785 } 789 }
786 } 790 }
787 791
788 } // namespace content 792 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698