| Index: content/browser/renderer_host/video_capture_memory.cc
|
| ===================================================================
|
| --- content/browser/renderer_host/video_capture_memory.cc (revision 0)
|
| +++ content/browser/renderer_host/video_capture_memory.cc (revision 0)
|
| @@ -0,0 +1,108 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/renderer_host/video_capture_memory.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/stl_util-inl.h"
|
| +#include "media/video/capture/video_capture_color_conversion.h"
|
| +
|
| +// The number of TransportDIBs VideoCaptureMemory allocate.
|
| +static const unsigned int kNoOfDIBS = 3;
|
| +
|
| +VideoCaptureMemory::VideoCaptureMemory(
|
| + VideoCaptureMemory::EventHandler* event_handler,
|
| + VCEntryId entry)
|
| + : event_handler_(*event_handler),
|
| + entry_id_(entry) {}
|
| +
|
| +VideoCaptureMemory::~VideoCaptureMemory() {
|
| + // Delete all TransportDIBs
|
| + STLDeleteContainerPairSecondPointers(owned_dibs_.begin(),
|
| + owned_dibs_.end());
|
| + owned_dibs_.clear();
|
| +}
|
| +
|
| +VideoCaptureMemory::VCEntryId VideoCaptureMemory::entry_id() {
|
| + return entry_id_;
|
| +}
|
| +
|
| +bool VideoCaptureMemory::AddTransportDIB(TransportDIB::Handle handle) {
|
| +// Check if we own this handle
|
| + const bool own_dib = owned_dibs_.find(handle) != owned_dibs_.end();
|
| + if (!own_dib) {
|
| + return false;
|
| + }
|
| +
|
| + lock_.Acquire();
|
| + free_dibs_.push_back(handle);
|
| + lock_.Release();
|
| + return true;
|
| +}
|
| +
|
| +bool VideoCaptureMemory::ReadyToDelete() {
|
| + base::AutoLock lock(lock_);
|
| + return free_dibs_.size() == owned_dibs_.size();
|
| +}
|
| +
|
| +void VideoCaptureMemory::OnIncomingCapturedFrame(const uint8* data,
|
| + int length,
|
| + base::Time timestamp) {
|
| + TransportDIB::Handle handle;
|
| + // Check if there is a TransportDIB to fill.
|
| + bool buffer_exist = false;
|
| + lock_.Acquire();
|
| + if (free_dibs_.size() > 0) {
|
| + handle = free_dibs_.back();
|
| + free_dibs_.pop_back();
|
| + buffer_exist = true;
|
| + }
|
| + lock_.Release();
|
| +
|
| + if (!buffer_exist) {
|
| + return;
|
| + }
|
| +
|
| + TransportDIB* dib = TransportDIB::Map(handle);
|
| + uint8* target = static_cast<uint8*> (dib->memory());
|
| + CHECK(dib->size() >= (unsigned int) (frame_info_.width*frame_info_.height*3) /
|
| + 2);
|
| +
|
| + // Do color conversion from the camera format to I420.
|
| + media::VideoCaptureColorConversion::ConvertToI420(frame_info_.color, data,
|
| + frame_info_.width,
|
| + frame_info_.height,
|
| + target);
|
| + event_handler_.OnBufferReady(entry_id_, handle, timestamp);
|
| +}
|
| +
|
| +void VideoCaptureMemory::OnError() {
|
| + event_handler_.OnError(entry_id_);
|
| +}
|
| +
|
| +void VideoCaptureMemory::OnFrameInfo(
|
| + const media::VideoCaptureDevice::Capability& info) {
|
| + DCHECK(owned_dibs_.empty());
|
| + // Lock needed since the buffers are used in OnIncomingFrame.
|
| + // And we need to use it there in order to avoid memcpy of complete frames
|
| + lock_.Acquire();
|
| + const size_t needed_size = (info.width * info.height * 3) / 2;
|
| + for (unsigned int i = 0; i < kNoOfDIBS; ++i) {
|
| + TransportDIB* dib = TransportDIB::Create(needed_size, i);
|
| + if (!dib) {
|
| + break;
|
| + }
|
| + owned_dibs_.insert(std::make_pair(dib->handle(), dib));
|
| + free_dibs_.push_back(dib->handle());
|
| + }
|
| + frame_info_= info;
|
| + lock_.Release();
|
| +
|
| + // Check that all Dibs where created
|
| + if (owned_dibs_.size() != kNoOfDIBS) {
|
| + event_handler_.OnError(entry_id_);
|
| + }
|
| + event_handler_.OnFrameInfo(entry_id_, info.width, info.height,
|
| + info.frame_rate);
|
| +}
|
|
|