| Index: content/renderer/media/rtc_video_encoder.cc
 | 
| diff --git a/content/renderer/media/rtc_video_encoder.cc b/content/renderer/media/rtc_video_encoder.cc
 | 
| index 416317d36354f531bca3797711529fc9cc5b5f3f..1a4efcdc4e8220c4b630dde9919d6f3832031c38 100644
 | 
| --- a/content/renderer/media/rtc_video_encoder.cc
 | 
| +++ b/content/renderer/media/rtc_video_encoder.cc
 | 
| @@ -13,6 +13,7 @@
 | 
|  #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
 | 
|  #include "media/base/bitstream_buffer.h"
 | 
|  #include "media/base/video_frame.h"
 | 
| +#include "media/base/video_util.h"
 | 
|  #include "media/filters/gpu_video_accelerator_factories.h"
 | 
|  #include "media/video/video_encode_accelerator.h"
 | 
|  
 | 
| @@ -268,7 +269,8 @@ void RTCVideoEncoder::Impl::RequireBitstreamBuffers(
 | 
|  
 | 
|    for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) {
 | 
|      base::SharedMemory* shm =
 | 
| -        gpu_factories_->CreateSharedMemory(input_coded_size.GetArea() * 3 / 2);
 | 
| +        gpu_factories_->CreateSharedMemory(media::VideoFrame::AllocationSize(
 | 
| +            media::VideoFrame::I420, input_coded_size));
 | 
|      if (!shm) {
 | 
|        DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): "
 | 
|                       "failed to create input buffer " << i;
 | 
| @@ -396,47 +398,38 @@ void RTCVideoEncoder::Impl::EncodeOneFrame() {
 | 
|  
 | 
|    const int index = input_buffers_free_.back();
 | 
|    base::SharedMemory* input_buffer = input_buffers_[index];
 | 
| -
 | 
| -  // Do a strided copy of the input frame to match the input requirements for
 | 
| -  // the encoder.
 | 
| -  // TODO(sheu): support zero-copy from WebRTC.  http://crbug.com/269312
 | 
| -  const uint8_t* src = next_frame->buffer(webrtc::kYPlane);
 | 
| -  uint8* dst = reinterpret_cast<uint8*>(input_buffer->memory());
 | 
| -  uint8* const y_dst = dst;
 | 
| -  int width = input_frame_coded_size_.width();
 | 
| -  int stride = next_frame->stride(webrtc::kYPlane);
 | 
| -  for (int i = 0; i < next_frame->height(); ++i) {
 | 
| -    memcpy(dst, src, width);
 | 
| -    src += stride;
 | 
| -    dst += width;
 | 
| -  }
 | 
| -  src = next_frame->buffer(webrtc::kUPlane);
 | 
| -  width = input_frame_coded_size_.width() / 2;
 | 
| -  stride = next_frame->stride(webrtc::kUPlane);
 | 
| -  for (int i = 0; i < next_frame->height() / 2; ++i) {
 | 
| -    memcpy(dst, src, width);
 | 
| -    src += stride;
 | 
| -    dst += width;
 | 
| -  }
 | 
| -  src = next_frame->buffer(webrtc::kVPlane);
 | 
| -  width = input_frame_coded_size_.width() / 2;
 | 
| -  stride = next_frame->stride(webrtc::kVPlane);
 | 
| -  for (int i = 0; i < next_frame->height() / 2; ++i) {
 | 
| -    memcpy(dst, src, width);
 | 
| -    src += stride;
 | 
| -    dst += width;
 | 
| -  }
 | 
| -
 | 
|    scoped_refptr<media::VideoFrame> frame =
 | 
|        media::VideoFrame::WrapExternalSharedMemory(
 | 
|            media::VideoFrame::I420,
 | 
|            input_frame_coded_size_,
 | 
|            gfx::Rect(input_visible_size_),
 | 
|            input_visible_size_,
 | 
| -          y_dst,
 | 
| +          reinterpret_cast<uint8*>(input_buffer->memory()),
 | 
| +          input_buffer->mapped_size(),
 | 
|            input_buffer->handle(),
 | 
|            base::TimeDelta(),
 | 
|            base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index));
 | 
| +  if (!frame) {
 | 
| +    DLOG(ERROR) << "Impl::EncodeOneFrame(): failed to create frame";
 | 
| +    NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError);
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  // Do a strided copy of the input frame to match the input requirements for
 | 
| +  // the encoder.
 | 
| +  // TODO(sheu): support zero-copy from WebRTC.  http://crbug.com/269312
 | 
| +  media::CopyYPlane(next_frame->buffer(webrtc::kYPlane),
 | 
| +                    next_frame->stride(webrtc::kYPlane),
 | 
| +                    next_frame->height(),
 | 
| +                    frame.get());
 | 
| +  media::CopyUPlane(next_frame->buffer(webrtc::kUPlane),
 | 
| +                    next_frame->stride(webrtc::kUPlane),
 | 
| +                    next_frame->height(),
 | 
| +                    frame.get());
 | 
| +  media::CopyVPlane(next_frame->buffer(webrtc::kVPlane),
 | 
| +                    next_frame->stride(webrtc::kVPlane),
 | 
| +                    next_frame->height(),
 | 
| +                    frame.get());
 | 
|  
 | 
|    video_encoder_->Encode(frame, next_frame_keyframe);
 | 
|    input_buffers_free_.pop_back();
 | 
| @@ -485,6 +478,7 @@ RTCVideoEncoder::RTCVideoEncoder(
 | 
|      : video_codec_type_(type),
 | 
|        video_codec_profile_(profile),
 | 
|        gpu_factories_(gpu_factories),
 | 
| +      weak_this_factory_(this),
 | 
|        encoded_image_callback_(NULL),
 | 
|        impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
 | 
|    DVLOG(1) << "RTCVideoEncoder(): profile=" << profile;
 | 
| @@ -506,8 +500,8 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
 | 
|    DCHECK(thread_checker_.CalledOnValidThread());
 | 
|    DCHECK(!impl_);
 | 
|  
 | 
| -  weak_this_factory_.reset(new base::WeakPtrFactory<RTCVideoEncoder>(this));
 | 
| -  impl_ = new Impl(weak_this_factory_->GetWeakPtr(), gpu_factories_);
 | 
| +  weak_this_factory_.InvalidateWeakPtrs();
 | 
| +  impl_ = new Impl(weak_this_factory_.GetWeakPtr(), gpu_factories_);
 | 
|    base::WaitableEvent initialization_waiter(true, false);
 | 
|    int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
 | 
|    gpu_factories_->GetMessageLoop()->PostTask(
 | 
| @@ -578,7 +572,7 @@ int32_t RTCVideoEncoder::Release() {
 | 
|      gpu_factories_->GetMessageLoop()->PostTask(
 | 
|          FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_));
 | 
|      impl_ = NULL;
 | 
| -    weak_this_factory_.reset();
 | 
| +    weak_this_factory_.InvalidateWeakPtrs();
 | 
|      impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
 | 
|    }
 | 
|    return WEBRTC_VIDEO_CODEC_OK;
 | 
| 
 |