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

Unified Diff: content/browser/renderer_host/media/video_capture_controller.cc

Issue 83793004: Implement IPCs and VideoCapture::Client interfaces for texture capture (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: e296ac98 Win32 bits. Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/media/video_capture_controller.cc
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 5dff5c2c91339cebf69f5691df11ec851e287dd9..5bd8ac2e6197265b21a949beae5625a99c85bed4 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/media/video_capture_controller.h"
+#include <map>
#include <set>
#include "base/bind.h"
@@ -12,6 +13,7 @@
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/public/browser/browser_thread.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/base/yuv_convert.h"
@@ -74,8 +76,10 @@ struct VideoCaptureController::ControllerClient {
// Buffers that are currently known to this client.
std::set<int> known_buffers;
- // Buffers currently held by this client.
- std::set<int> active_buffers;
+ // Buffers currently held by this client, and syncpoint callback to call when
+ // they are returned from the client.
+ typedef std::map<int, scoped_refptr<media::VideoFrame> > ActiveBufferMap;
+ ActiveBufferMap active_buffers;
// State of capture session, controlled by VideoCaptureManager directly. This
// transitions to true as soon as StopSession() occurs, at which point the
@@ -110,17 +114,16 @@ class VideoCaptureController::VideoCaptureDeviceClient
virtual scoped_refptr<Buffer> ReserveOutputBuffer(
media::VideoFrame::Format format,
const gfx::Size& size) OVERRIDE;
- virtual void OnIncomingCapturedFrame(const uint8* data,
- int length,
- base::TimeTicks timestamp,
- int rotation,
- const VideoCaptureFormat& frame_format)
- OVERRIDE;
- virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer,
- media::VideoFrame::Format format,
- const gfx::Size& dimensions,
- base::TimeTicks timestamp,
- int frame_rate) OVERRIDE;
+ virtual void OnIncomingCapturedData(const uint8* data,
+ int length,
+ const VideoCaptureFormat& frame_format,
+ int rotation,
+ base::TimeTicks timestamp) OVERRIDE;
+ virtual void OnIncomingCapturedVideoFrame(
+ const scoped_refptr<Buffer>& buffer,
+ const VideoCaptureFormat& buffer_format,
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp) OVERRIDE;
virtual void OnError(const std::string& reason) OVERRIDE;
private:
@@ -206,11 +209,11 @@ int VideoCaptureController::RemoveClient(
return kInvalidMediaCaptureSessionId;
// Take back all buffers held by the |client|.
- for (std::set<int>::iterator buffer_it = client->active_buffers.begin();
+ for (ControllerClient::ActiveBufferMap::iterator buffer_it =
+ client->active_buffers.begin();
buffer_it != client->active_buffers.end();
++buffer_it) {
- int buffer_id = *buffer_it;
- buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
+ buffer_pool_->RelinquishConsumerHold(buffer_it->first, 1);
}
client->active_buffers.clear();
@@ -236,17 +239,25 @@ void VideoCaptureController::StopSession(int session_id) {
void VideoCaptureController::ReturnBuffer(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
- int buffer_id) {
+ int buffer_id,
+ uint32 sync_point) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
ControllerClient* client = FindClient(id, event_handler, controller_clients_);
// If this buffer is not held by this client, or this client doesn't exist
// in controller, do nothing.
- if (!client || !client->active_buffers.erase(buffer_id)) {
+ ControllerClient::ActiveBufferMap::iterator iter;
+ if (!client || (iter = client->active_buffers.find(buffer_id)) ==
+ client->active_buffers.end()) {
NOTREACHED();
return;
}
+ scoped_refptr<media::VideoFrame> frame = iter->second;
+ client->active_buffers.erase(iter);
+
+ if (frame->format() == media::VideoFrame::NATIVE_TEXTURE)
+ frame->mailbox_holder()->sync_point = sync_point;
buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
}
@@ -264,13 +275,13 @@ VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer(
return DoReserveOutputBuffer(format, size);
}
-void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
+void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedData(
const uint8* data,
int length,
- base::TimeTicks timestamp,
+ const VideoCaptureFormat& frame_format,
int rotation,
- const VideoCaptureFormat& frame_format) {
- TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
+ base::TimeTicks timestamp) {
+ TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedData");
if (!frame_format.IsValid())
return;
@@ -303,9 +314,10 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
if (!buffer)
return;
+ uint8* yplane = NULL;
#if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
bool flip = false;
- uint8* yplane = reinterpret_cast<uint8*>(buffer->data());
+ yplane = reinterpret_cast<uint8*>(buffer->data());
uint8* uplane =
yplane +
media::VideoFrame::PlaneAllocationSize(
@@ -394,37 +406,48 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
// address all these #ifdef parts, see http://crbug.com/299611 .
NOTREACHED();
#endif // if !defined(AVOID_LIBYUV_FOR_ANDROID_WEBVIEW)
+ VideoCaptureFormat format(
+ dimensions, frame_format.frame_rate, media::PIXEL_FORMAT_I420);
+ scoped_refptr<media::VideoFrame> frame =
+ media::VideoFrame::WrapExternalPackedMemory(
+ media::VideoFrame::I420,
+ dimensions,
+ gfx::Rect(dimensions),
+ dimensions,
+ yplane,
+ media::VideoFrame::AllocationSize(media::VideoFrame::I420,
+ dimensions),
+ base::SharedMemory::NULLHandle(),
+ base::TimeDelta(),
+ base::Closure());
+ DCHECK(frame);
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(
- &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread,
+ &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
controller_,
buffer,
- dimensions,
- frame_format.frame_rate,
+ format,
+ frame,
timestamp));
}
-void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
+void
+VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
const scoped_refptr<Buffer>& buffer,
- media::VideoFrame::Format format,
- const gfx::Size& dimensions,
- base::TimeTicks timestamp,
- int frame_rate) {
- // The capture pipeline expects I420 for now.
- DCHECK_EQ(format, media::VideoFrame::I420)
- << "Non-I420 output buffer returned";
-
+ const VideoCaptureFormat& buffer_format,
+ const scoped_refptr<media::VideoFrame>& frame,
+ base::TimeTicks timestamp) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(
- &VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread,
+ &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread,
controller_,
buffer,
- dimensions,
- frame_rate,
+ buffer_format,
+ frame,
timestamp));
}
@@ -441,14 +464,18 @@ scoped_refptr<media::VideoCaptureDevice::Client::Buffer>
VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer(
media::VideoFrame::Format format,
const gfx::Size& dimensions) {
- // The capture pipeline expects I420 for now.
- DCHECK_EQ(format, media::VideoFrame::I420)
- << "Non-I420 output buffer requested";
+ size_t frame_bytes = 0;
+ if (format == media::VideoFrame::NATIVE_TEXTURE) {
+ DCHECK_EQ(dimensions.width(), 0);
+ DCHECK_EQ(dimensions.height(), 0);
+ } else {
+ // The capture pipeline expects I420 for now.
+ DCHECK_EQ(format, media::VideoFrame::I420)
+ << "Non-I420 output buffer format " << format << " requested";
+ frame_bytes = media::VideoFrame::AllocationSize(format, dimensions);
+ }
int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId;
- const size_t frame_bytes =
- media::VideoFrame::AllocationSize(format, dimensions);
-
int buffer_id =
buffer_pool_->ReserveForProducer(frame_bytes, &buffer_id_to_drop);
if (buffer_id == VideoCaptureBufferPool::kInvalidId)
@@ -475,17 +502,14 @@ VideoCaptureController::~VideoCaptureController() {
controller_clients_.end());
}
-void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread(
- scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer,
- const gfx::Size& dimensions,
- int frame_rate,
+void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
+ const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
+ const media::VideoCaptureFormat& buffer_format,
+ const scoped_refptr<media::VideoFrame>& frame,
base::TimeTicks timestamp) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId);
- VideoCaptureFormat frame_format(
- dimensions, frame_rate, media::PIXEL_FORMAT_I420);
-
int count = 0;
if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
for (ControllerClients::iterator client_it = controller_clients_.begin();
@@ -494,19 +518,30 @@ void VideoCaptureController::DoIncomingCapturedI420BufferOnIOThread(
if (client->session_closed)
continue;
- bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
- if (is_new_buffer) {
- // On the first use of a buffer on a client, share the memory handle.
- size_t memory_size = 0;
- base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess(
- buffer->id(), client->render_process_handle, &memory_size);
- client->event_handler->OnBufferCreated(
- client->controller_id, remote_handle, memory_size, buffer->id());
+ if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) {
+ client->event_handler->OnMailboxBufferReady(client->controller_id,
+ buffer->id(),
+ *frame->mailbox_holder(),
+ buffer_format,
+ timestamp);
+ } else {
+ bool is_new_buffer = client->known_buffers.insert(buffer->id()).second;
+ if (is_new_buffer) {
+ // On the first use of a buffer on a client, share the memory handle.
+ size_t memory_size = 0;
+ base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess(
+ buffer->id(), client->render_process_handle, &memory_size);
+ client->event_handler->OnBufferCreated(
+ client->controller_id, remote_handle, memory_size, buffer->id());
+ }
+
+ client->event_handler->OnBufferReady(
+ client->controller_id, buffer->id(), buffer_format, timestamp);
}
- client->event_handler->OnBufferReady(
- client->controller_id, buffer->id(), timestamp, frame_format);
- bool inserted = client->active_buffers.insert(buffer->id()).second;
+ bool inserted =
+ client->active_buffers.insert(std::make_pair(buffer->id(), frame))
+ .second;
DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id();
count++;
}

Powered by Google App Engine
This is Rietveld 408576698