| Index: content/browser/renderer_host/media/video_capture_host.cc
|
| diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc
|
| index 9c4fc77a2dafaee5b5b2e81963776577fd1e6e74..0eb6fbc7a0b35f7da5a83b3c5c14c20762b735d0 100644
|
| --- a/content/browser/renderer_host/media/video_capture_host.cc
|
| +++ b/content/browser/renderer_host/media/video_capture_host.cc
|
| @@ -10,17 +10,21 @@
|
| #include "content/browser/browser_main_loop.h"
|
| #include "content/browser/renderer_host/media/media_stream_manager.h"
|
| #include "content/browser/renderer_host/media/video_capture_manager.h"
|
| +#include "content/common/media/encoded_video_capture_messages.h"
|
| #include "content/common/media/video_capture_messages.h"
|
| +#include "media/video/video_encode_types.h"
|
|
|
| namespace content {
|
|
|
| struct VideoCaptureHost::Entry {
|
| Entry(VideoCaptureController* controller)
|
| - : controller(controller) {}
|
| + : controller(controller),
|
| + encoded(false) {}
|
|
|
| ~Entry() {}
|
|
|
| scoped_refptr<VideoCaptureController> controller;
|
| + bool encoded;
|
| };
|
|
|
| VideoCaptureHost::VideoCaptureHost() {}
|
| @@ -57,36 +61,58 @@ void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id) {
|
| this, controller_id));
|
| }
|
|
|
| -void VideoCaptureHost::OnBufferCreated(
|
| - const VideoCaptureControllerID& controller_id,
|
| - base::SharedMemoryHandle handle,
|
| - int length,
|
| - int buffer_id) {
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - base::Bind(&VideoCaptureHost::DoSendNewBufferOnIOThread,
|
| - this, controller_id, handle, length, buffer_id));
|
| -}
|
| -
|
| void VideoCaptureHost::OnBufferReady(
|
| const VideoCaptureControllerID& controller_id,
|
| int buffer_id,
|
| - base::Time timestamp) {
|
| + size_t data_size,
|
| + base::Time timestamp,
|
| + bool key_frame) {
|
| BrowserThread::PostTask(
|
| BrowserThread::IO, FROM_HERE,
|
| base::Bind(&VideoCaptureHost::DoSendFilledBufferOnIOThread,
|
| - this, controller_id, buffer_id, timestamp));
|
| + this, controller_id, buffer_id, data_size, timestamp,
|
| + key_frame));
|
| }
|
|
|
| void VideoCaptureHost::OnFrameInfo(
|
| const VideoCaptureControllerID& controller_id,
|
| - int width,
|
| - int height,
|
| - int frame_per_second) {
|
| + const media::VideoCaptureParams& params,
|
| + const std::vector<base::SharedMemoryHandle>& buffers,
|
| + size_t buffer_size) {
|
| BrowserThread::PostTask(
|
| BrowserThread::IO, FROM_HERE,
|
| base::Bind(&VideoCaptureHost::DoSendFrameInfoOnIOThread,
|
| - this, controller_id, width, height, frame_per_second));
|
| + this,
|
| + controller_id,
|
| + params,
|
| + buffers,
|
| + buffer_size));
|
| +}
|
| +
|
| +void VideoCaptureHost::OnEncodedFrameInfo(
|
| + const VideoCaptureControllerID& controller_id,
|
| + const media::VideoEncodingParameters& params,
|
| + const std::vector<base::SharedMemoryHandle>& buffers,
|
| + size_t buffer_size) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&VideoCaptureHost::DoSendEncodedFrameInfoOnIOThread,
|
| + this,
|
| + controller_id,
|
| + params,
|
| + buffers,
|
| + buffer_size));
|
| +}
|
| +
|
| +void VideoCaptureHost::OnBitstreamConfigChanged(
|
| + const VideoCaptureControllerID& controller_id,
|
| + const media::RuntimeVideoEncodingParameters& params) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&VideoCaptureHost::DoBitstreamConfigChangedOnIOThread,
|
| + this,
|
| + controller_id,
|
| + params));
|
| }
|
|
|
| void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) {
|
| @@ -96,71 +122,120 @@ void VideoCaptureHost::OnEnded(const VideoCaptureControllerID& controller_id) {
|
| base::Bind(&VideoCaptureHost::DoEndedOnIOThread, this, controller_id));
|
| }
|
|
|
| -void VideoCaptureHost::DoSendNewBufferOnIOThread(
|
| +void VideoCaptureHost::DoSendFilledBufferOnIOThread(
|
| const VideoCaptureControllerID& controller_id,
|
| - base::SharedMemoryHandle handle,
|
| - int length,
|
| - int buffer_id) {
|
| + int buffer_id, size_t size, base::Time timestamp, bool key_frame) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| - if (entries_.find(controller_id) == entries_.end())
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| return;
|
|
|
| - Send(new VideoCaptureMsg_NewBuffer(controller_id.device_id, handle,
|
| - length, buffer_id));
|
| + if (iter->second->encoded) {
|
| + media::BufferEncodingMetadata metadata;
|
| + metadata.timestamp = timestamp;
|
| + metadata.key_frame = key_frame;
|
| + Send(new EncodedVideoCaptureMsg_BitstreamReady(controller_id.device_id,
|
| + buffer_id,
|
| + size,
|
| + metadata));
|
| + } else {
|
| + Send(new VideoCaptureMsg_BufferReady(controller_id.device_id, buffer_id,
|
| + timestamp));
|
| + }
|
| }
|
|
|
| -void VideoCaptureHost::DoSendFilledBufferOnIOThread(
|
| - const VideoCaptureControllerID& controller_id,
|
| - int buffer_id, base::Time timestamp) {
|
| +void VideoCaptureHost::DoHandleErrorOnIOThread(
|
| + const VideoCaptureControllerID& controller_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| - if (entries_.find(controller_id) == entries_.end())
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| return;
|
|
|
| - Send(new VideoCaptureMsg_BufferReady(controller_id.device_id, buffer_id,
|
| - timestamp));
|
| + if (iter->second->encoded) {
|
| + Send(new EncodedVideoCaptureHostMsg_DestroyBitstream(
|
| + controller_id.device_id));
|
| + } else {
|
| + Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
|
| + VIDEO_CAPTURE_STATE_ERROR));
|
| + }
|
| + DeleteVideoCaptureControllerOnIOThread(controller_id);
|
| }
|
|
|
| -void VideoCaptureHost::DoHandleErrorOnIOThread(
|
| - const VideoCaptureControllerID& controller_id) {
|
| +void VideoCaptureHost::DoSendFrameInfoOnIOThread(
|
| + const VideoCaptureControllerID& controller_id,
|
| + const media::VideoCaptureParams& params,
|
| + const std::vector<base::SharedMemoryHandle>& buffers,
|
| + size_t buffer_size) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| - if (entries_.find(controller_id) == entries_.end())
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| return;
|
|
|
| + DCHECK(!iter->second->encoded);
|
| + Send(new VideoCaptureMsg_DeviceInfo(controller_id.device_id, params));
|
| Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
|
| - VIDEO_CAPTURE_STATE_ERROR));
|
| - DeleteVideoCaptureControllerOnIOThread(controller_id);
|
| + VIDEO_CAPTURE_STATE_STARTED));
|
| + for (size_t i = 0; i < buffers.size(); ++i) {
|
| + Send(new VideoCaptureMsg_NewBuffer(controller_id.device_id,
|
| + buffers[i],
|
| + buffer_size,
|
| + i));
|
| + }
|
| +}
|
| +
|
| +void VideoCaptureHost::DoSendEncodedFrameInfoOnIOThread(
|
| + const VideoCaptureControllerID& controller_id,
|
| + const media::VideoEncodingParameters& params,
|
| + const std::vector<base::SharedMemoryHandle>& buffers,
|
| + size_t buffer_size) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| + return;
|
| +
|
| + DCHECK(iter->second->encoded);
|
| + Send(new EncodedVideoCaptureMsg_BitstreamCreated(controller_id.device_id,
|
| + params,
|
| + buffers,
|
| + buffer_size));
|
| }
|
|
|
| void VideoCaptureHost::DoEndedOnIOThread(
|
| const VideoCaptureControllerID& controller_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| DVLOG(1) << "VideoCaptureHost::DoEndedOnIOThread";
|
| - if (entries_.find(controller_id) == entries_.end())
|
| +
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| return;
|
|
|
| - Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
|
| - VIDEO_CAPTURE_STATE_ENDED));
|
| + if (iter->second->encoded) {
|
| + Send(new EncodedVideoCaptureHostMsg_DestroyBitstream(
|
| + controller_id.device_id));
|
| + } else {
|
| + Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
|
| + VIDEO_CAPTURE_STATE_ENDED));
|
| + }
|
| DeleteVideoCaptureControllerOnIOThread(controller_id);
|
| }
|
|
|
| -void VideoCaptureHost::DoSendFrameInfoOnIOThread(
|
| +void VideoCaptureHost::DoBitstreamConfigChangedOnIOThread(
|
| const VideoCaptureControllerID& controller_id,
|
| - int width, int height, int frame_per_second) {
|
| + const media::RuntimeVideoEncodingParameters& params) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| - if (entries_.find(controller_id) == entries_.end())
|
| + EntryMap::iterator iter = entries_.find(controller_id);
|
| + if (iter == entries_.end())
|
| return;
|
| -
|
| - media::VideoCaptureParams params;
|
| - params.width = width;
|
| - params.height = height;
|
| - params.frame_per_second = frame_per_second;
|
| - Send(new VideoCaptureMsg_DeviceInfo(controller_id.device_id, params));
|
| - Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
|
| - VIDEO_CAPTURE_STATE_STARTED));
|
| + if (!iter->second->encoded)
|
| + return;
|
| + Send(new EncodedVideoCaptureMsg_BitstreamConfigChanged(
|
| + controller_id.device_id,
|
| + params));
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -173,6 +248,16 @@ bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message,
|
| IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, OnPauseCapture)
|
| IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, OnStopCapture)
|
| IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, OnReceiveEmptyBuffer)
|
| + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_GetCapability,
|
| + OnGetCapability)
|
| + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_CreateBitstream,
|
| + OnCreateBitstream)
|
| + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_DestroyBitstream,
|
| + OnDestroyBitstream)
|
| + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_TryConfigureBitstream,
|
| + OnTryConfigureBitstream)
|
| + IPC_MESSAGE_HANDLER(EncodedVideoCaptureHostMsg_BitstreamBufferConsumed,
|
| + OnBitstreamBufferConsumed)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP_EX()
|
|
|
| @@ -230,6 +315,13 @@ void VideoCaptureHost::DoControllerAddedOnIOThread(
|
| controller->StartCapture(controller_id, this, peer_handle(), params);
|
| }
|
|
|
| +void VideoCaptureHost::OnPauseCapture(int device_id) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
|
| + // Not used.
|
| + Send(new VideoCaptureMsg_StateChanged(device_id, VIDEO_CAPTURE_STATE_ERROR));
|
| +}
|
| +
|
| void VideoCaptureHost::OnStopCapture(int device_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id;
|
| @@ -241,25 +333,98 @@ void VideoCaptureHost::OnStopCapture(int device_id) {
|
| DeleteVideoCaptureControllerOnIOThread(controller_id);
|
| }
|
|
|
| -void VideoCaptureHost::OnPauseCapture(int device_id) {
|
| +void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - DVLOG(1) << "VideoCaptureHost::OnPauseCapture, device_id " << device_id;
|
| - // Not used.
|
| - Send(new VideoCaptureMsg_StateChanged(device_id, VIDEO_CAPTURE_STATE_ERROR));
|
| +
|
| + VideoCaptureControllerID controller_id(device_id);
|
| + EntryMap::iterator it = entries_.find(controller_id);
|
| + if (it != entries_.end()) {
|
| + scoped_refptr<VideoCaptureController> controller = it->second->controller;
|
| + if (controller.get())
|
| + controller->ReturnBuffer(controller_id, this, buffer_id);
|
| + }
|
| }
|
|
|
| -void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) {
|
| +void VideoCaptureHost::OnGetCapability(
|
| + int device_id,
|
| + const media::VideoCaptureSessionId& session_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DVLOG(1) << "VideoCaptureHost::OnGetCapability, session_id " << session_id;
|
| + GetVideoCaptureManager()->RequestEncodingCapability(
|
| + session_id,
|
| + base::Bind(&VideoCaptureHost::OnEncodingCapabilityFound,
|
| + this,
|
| + device_id));
|
| +}
|
| +
|
| +void VideoCaptureHost::OnEncodingCapabilityFound(
|
| + int device_id,
|
| + const media::VideoEncodingCapability& capability) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&VideoCaptureHost::DoEncodingCapabilityFoundOnIOThread,
|
| + this, device_id, capability));
|
| +}
|
| +
|
| +void VideoCaptureHost::DoEncodingCapabilityFoundOnIOThread(
|
| + int device_id,
|
| + const media::VideoEncodingCapability& capability) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + Send(new EncodedVideoCaptureMsg_CapabilityAvailable(device_id, capability));
|
| +}
|
| +
|
| +void VideoCaptureHost::OnCreateBitstream(
|
| + int device_id,
|
| + const media::VideoCaptureSessionId& session_id,
|
| + const media::VideoEncodingParameters& params) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DVLOG(1) << "VideoCaptureHost::OnCreateBitstream, device_id " << device_id
|
| + << ", session_id " << session_id;
|
| + media::VideoCaptureParams cap_params;
|
| + memset(&cap_params, 0, sizeof(cap_params));
|
| + cap_params.width = params.resolution.width();
|
| + cap_params.height = params.resolution.height();
|
| + cap_params.frame_per_second = params.frames_per_second;
|
| + cap_params.session_id = session_id;
|
| +
|
| + VideoCaptureControllerID controller_id(device_id);
|
| + DCHECK(entries_.find(controller_id) == entries_.end());
|
| + Entry* entry = new Entry(NULL);
|
| + entry->encoded = true;
|
| + entries_[controller_id] = entry;
|
| + GetVideoCaptureManager()->AddController(
|
| + cap_params, this, base::Bind(&VideoCaptureHost::OnControllerAdded, this,
|
| + device_id, cap_params));
|
| +}
|
| +
|
| +void VideoCaptureHost::OnDestroyBitstream(int device_id) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DVLOG(1) << "VideoCaptureHost::OnDestroyBitstream, device_id " << device_id;
|
| + // Proxy over to OnStopCapture.
|
| + OnStopCapture(device_id);
|
| +}
|
| +
|
| +void VideoCaptureHost::OnTryConfigureBitstream(
|
| + int device_id,
|
| + const media::RuntimeVideoEncodingParameters& params) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + DVLOG(1) << "VideoCaptureHost::OnTryConfigureBitstream, device_id "
|
| + << device_id;
|
|
|
| VideoCaptureControllerID controller_id(device_id);
|
| EntryMap::iterator it = entries_.find(controller_id);
|
| if (it != entries_.end()) {
|
| scoped_refptr<VideoCaptureController> controller = it->second->controller;
|
| if (controller.get())
|
| - controller->ReturnBuffer(controller_id, this, buffer_id);
|
| + controller->TryConfigureEncodedBitstream(params);
|
| }
|
| }
|
|
|
| +void VideoCaptureHost::OnBitstreamBufferConsumed(int device_id, int buffer_id) {
|
| + // Proxy over to OnReceiveEmptyBuffer.
|
| + OnReceiveEmptyBuffer(device_id, buffer_id);
|
| +}
|
| +
|
| void VideoCaptureHost::DeleteVideoCaptureControllerOnIOThread(
|
| const VideoCaptureControllerID& controller_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|