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

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

Issue 22875047: EVEA cleanup: use video utility functions in media::* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: b2b1b2ee Last comments. Created 7 years, 3 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
« no previous file with comments | « content/renderer/media/rtc_video_encoder.h ('k') | media/base/video_frame.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/message_loop/message_loop_proxy.h" 11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/synchronization/waitable_event.h" 12 #include "base/synchronization/waitable_event.h"
13 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" 13 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
14 #include "media/base/bitstream_buffer.h" 14 #include "media/base/bitstream_buffer.h"
15 #include "media/base/video_frame.h" 15 #include "media/base/video_frame.h"
16 #include "media/base/video_util.h"
16 #include "media/filters/gpu_video_accelerator_factories.h" 17 #include "media/filters/gpu_video_accelerator_factories.h"
17 #include "media/video/video_encode_accelerator.h" 18 #include "media/video/video_encode_accelerator.h"
18 19
19 #define NOTIFY_ERROR(x) \ 20 #define NOTIFY_ERROR(x) \
20 do { \ 21 do { \
21 DLOG(ERROR) << "calling NotifyError(): " << x; \ 22 DLOG(ERROR) << "calling NotifyError(): " << x; \
22 NotifyError(x); \ 23 NotifyError(x); \
23 } while (0) 24 } while (0)
24 25
25 namespace content { 26 namespace content {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 << ", output_buffer_size=" << output_buffer_size; 262 << ", output_buffer_size=" << output_buffer_size;
262 DCHECK(thread_checker_.CalledOnValidThread()); 263 DCHECK(thread_checker_.CalledOnValidThread());
263 264
264 if (!video_encoder_) 265 if (!video_encoder_)
265 return; 266 return;
266 267
267 input_frame_coded_size_ = input_coded_size; 268 input_frame_coded_size_ = input_coded_size;
268 269
269 for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) { 270 for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) {
270 base::SharedMemory* shm = 271 base::SharedMemory* shm =
271 gpu_factories_->CreateSharedMemory(input_coded_size.GetArea() * 3 / 2); 272 gpu_factories_->CreateSharedMemory(media::VideoFrame::AllocationSize(
273 media::VideoFrame::I420, input_coded_size));
272 if (!shm) { 274 if (!shm) {
273 DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): " 275 DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): "
274 "failed to create input buffer " << i; 276 "failed to create input buffer " << i;
275 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); 277 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
276 return; 278 return;
277 } 279 }
278 input_buffers_.push_back(shm); 280 input_buffers_.push_back(shm);
279 input_buffers_free_.push_back(i); 281 input_buffers_free_.push_back(i);
280 } 282 }
281 283
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 input_next_frame_ = NULL; 391 input_next_frame_ = NULL;
390 input_next_frame_keyframe_ = false; 392 input_next_frame_keyframe_ = false;
391 393
392 if (!video_encoder_) { 394 if (!video_encoder_) {
393 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR); 395 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR);
394 return; 396 return;
395 } 397 }
396 398
397 const int index = input_buffers_free_.back(); 399 const int index = input_buffers_free_.back();
398 base::SharedMemory* input_buffer = input_buffers_[index]; 400 base::SharedMemory* input_buffer = input_buffers_[index];
399
400 // Do a strided copy of the input frame to match the input requirements for
401 // the encoder.
402 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
403 const uint8_t* src = next_frame->buffer(webrtc::kYPlane);
404 uint8* dst = reinterpret_cast<uint8*>(input_buffer->memory());
405 uint8* const y_dst = dst;
406 int width = input_frame_coded_size_.width();
407 int stride = next_frame->stride(webrtc::kYPlane);
408 for (int i = 0; i < next_frame->height(); ++i) {
409 memcpy(dst, src, width);
410 src += stride;
411 dst += width;
412 }
413 src = next_frame->buffer(webrtc::kUPlane);
414 width = input_frame_coded_size_.width() / 2;
415 stride = next_frame->stride(webrtc::kUPlane);
416 for (int i = 0; i < next_frame->height() / 2; ++i) {
417 memcpy(dst, src, width);
418 src += stride;
419 dst += width;
420 }
421 src = next_frame->buffer(webrtc::kVPlane);
422 width = input_frame_coded_size_.width() / 2;
423 stride = next_frame->stride(webrtc::kVPlane);
424 for (int i = 0; i < next_frame->height() / 2; ++i) {
425 memcpy(dst, src, width);
426 src += stride;
427 dst += width;
428 }
429
430 scoped_refptr<media::VideoFrame> frame = 401 scoped_refptr<media::VideoFrame> frame =
431 media::VideoFrame::WrapExternalSharedMemory( 402 media::VideoFrame::WrapExternalSharedMemory(
432 media::VideoFrame::I420, 403 media::VideoFrame::I420,
433 input_frame_coded_size_, 404 input_frame_coded_size_,
434 gfx::Rect(input_visible_size_), 405 gfx::Rect(input_visible_size_),
435 input_visible_size_, 406 input_visible_size_,
436 y_dst, 407 reinterpret_cast<uint8*>(input_buffer->memory()),
408 input_buffer->mapped_size(),
437 input_buffer->handle(), 409 input_buffer->handle(),
438 base::TimeDelta(), 410 base::TimeDelta(),
439 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)); 411 base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index));
412 if (!frame) {
413 DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame";
414 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
415 return;
416 }
417
418 // Do a strided copy of the input frame to match the input requirements for
419 // the encoder.
420 // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312
421 media::CopyYPlane(next_frame->buffer(webrtc::kYPlane),
422 next_frame->stride(webrtc::kYPlane),
423 next_frame->height(),
424 frame.get());
425 media::CopyUPlane(next_frame->buffer(webrtc::kUPlane),
426 next_frame->stride(webrtc::kUPlane),
427 next_frame->height(),
428 frame.get());
429 media::CopyVPlane(next_frame->buffer(webrtc::kVPlane),
430 next_frame->stride(webrtc::kVPlane),
431 next_frame->height(),
432 frame.get());
440 433
441 video_encoder_->Encode(frame, next_frame_keyframe); 434 video_encoder_->Encode(frame, next_frame_keyframe);
442 input_buffers_free_.pop_back(); 435 input_buffers_free_.pop_back();
443 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); 436 SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK);
444 } 437 }
445 438
446 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) { 439 void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) {
447 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index; 440 DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index;
448 DCHECK(thread_checker_.CalledOnValidThread()); 441 DCHECK(thread_checker_.CalledOnValidThread());
449 DCHECK_GE(index, 0); 442 DCHECK_GE(index, 0);
(...skipping 28 matching lines...) Expand all
478 // 471 //
479 //////////////////////////////////////////////////////////////////////////////// 472 ////////////////////////////////////////////////////////////////////////////////
480 473
481 RTCVideoEncoder::RTCVideoEncoder( 474 RTCVideoEncoder::RTCVideoEncoder(
482 webrtc::VideoCodecType type, 475 webrtc::VideoCodecType type,
483 media::VideoCodecProfile profile, 476 media::VideoCodecProfile profile,
484 const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) 477 const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories)
485 : video_codec_type_(type), 478 : video_codec_type_(type),
486 video_codec_profile_(profile), 479 video_codec_profile_(profile),
487 gpu_factories_(gpu_factories), 480 gpu_factories_(gpu_factories),
481 weak_this_factory_(this),
488 encoded_image_callback_(NULL), 482 encoded_image_callback_(NULL),
489 impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) { 483 impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
490 DVLOG(1) << "RTCVideoEncoder(): profile=" << profile; 484 DVLOG(1) << "RTCVideoEncoder(): profile=" << profile;
491 } 485 }
492 486
493 RTCVideoEncoder::~RTCVideoEncoder() { 487 RTCVideoEncoder::~RTCVideoEncoder() {
494 DCHECK(thread_checker_.CalledOnValidThread()); 488 DCHECK(thread_checker_.CalledOnValidThread());
495 Release(); 489 Release();
496 DCHECK(!impl_); 490 DCHECK(!impl_);
497 } 491 }
498 492
499 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, 493 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
500 int32_t number_of_cores, 494 int32_t number_of_cores,
501 uint32_t max_payload_size) { 495 uint32_t max_payload_size) {
502 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType 496 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType
503 << ", width=" << codec_settings->width 497 << ", width=" << codec_settings->width
504 << ", height=" << codec_settings->height 498 << ", height=" << codec_settings->height
505 << ", startBitrate=" << codec_settings->startBitrate; 499 << ", startBitrate=" << codec_settings->startBitrate;
506 DCHECK(thread_checker_.CalledOnValidThread()); 500 DCHECK(thread_checker_.CalledOnValidThread());
507 DCHECK(!impl_); 501 DCHECK(!impl_);
508 502
509 weak_this_factory_.reset(new base::WeakPtrFactory<RTCVideoEncoder>(this)); 503 weak_this_factory_.InvalidateWeakPtrs();
510 impl_ = new Impl(weak_this_factory_->GetWeakPtr(), gpu_factories_); 504 impl_ = new Impl(weak_this_factory_.GetWeakPtr(), gpu_factories_);
511 base::WaitableEvent initialization_waiter(true, false); 505 base::WaitableEvent initialization_waiter(true, false);
512 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; 506 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
513 gpu_factories_->GetMessageLoop()->PostTask( 507 gpu_factories_->GetMessageLoop()->PostTask(
514 FROM_HERE, 508 FROM_HERE,
515 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, 509 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA,
516 impl_, 510 impl_,
517 gfx::Size(codec_settings->width, codec_settings->height), 511 gfx::Size(codec_settings->width, codec_settings->height),
518 codec_settings->startBitrate, 512 codec_settings->startBitrate,
519 video_codec_profile_, 513 video_codec_profile_,
520 &initialization_waiter, 514 &initialization_waiter,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 DVLOG(3) << "Release()"; 565 DVLOG(3) << "Release()";
572 DCHECK(thread_checker_.CalledOnValidThread()); 566 DCHECK(thread_checker_.CalledOnValidThread());
573 567
574 // Reset the gpu_factory_, in case we reuse this encoder. 568 // Reset the gpu_factory_, in case we reuse this encoder.
575 gpu_factories_->Abort(); 569 gpu_factories_->Abort();
576 gpu_factories_ = gpu_factories_->Clone(); 570 gpu_factories_ = gpu_factories_->Clone();
577 if (impl_) { 571 if (impl_) {
578 gpu_factories_->GetMessageLoop()->PostTask( 572 gpu_factories_->GetMessageLoop()->PostTask(
579 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); 573 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_));
580 impl_ = NULL; 574 impl_ = NULL;
581 weak_this_factory_.reset(); 575 weak_this_factory_.InvalidateWeakPtrs();
582 impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED; 576 impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
583 } 577 }
584 return WEBRTC_VIDEO_CODEC_OK; 578 return WEBRTC_VIDEO_CODEC_OK;
585 } 579 }
586 580
587 int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) { 581 int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) {
588 DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss 582 DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss
589 << ", rtt=" << rtt; 583 << ", rtt=" << rtt;
590 DCHECK(thread_checker_.CalledOnValidThread()); 584 DCHECK(thread_checker_.CalledOnValidThread());
591 // Ignored. 585 // Ignored.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 DCHECK(thread_checker_.CalledOnValidThread()); 643 DCHECK(thread_checker_.CalledOnValidThread());
650 DVLOG(1) << "NotifyError(): error=" << error; 644 DVLOG(1) << "NotifyError(): error=" << error;
651 645
652 impl_status_ = error; 646 impl_status_ = error;
653 gpu_factories_->GetMessageLoop()->PostTask( 647 gpu_factories_->GetMessageLoop()->PostTask(
654 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); 648 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_));
655 impl_ = NULL; 649 impl_ = NULL;
656 } 650 }
657 651
658 } // namespace content 652 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/rtc_video_encoder.h ('k') | media/base/video_frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698