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..81fab52df64b4c8562eda4fa4513b7069e5bf512 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)); |
hshi1
2013/06/20 22:51:02
How can browser send EncodedVideoCaptureHostMsg to
sheu
2013/08/22 22:40:31
Done.
|
+ } 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_GetCapabilities, |
+ OnGetCapabilities) |
+ 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. |
Ami GONE FROM CHROMIUM
2013/06/18 18:35:55
NOTREACHED?
piman
2013/06/19 18:33:51
Not NOTREACHED since it can be reached by a malici
|
+ 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::OnGetCapabilities( |
+ int device_id, |
+ const media::VideoCaptureSessionId& session_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DVLOG(1) << "VideoCaptureHost::OnGetCapabilities, session_id " << session_id; |
+ GetVideoCaptureManager()->RequestEncodingCapabilities( |
+ session_id, |
+ base::Bind(&VideoCaptureHost::OnEncodingCapabilitiesFound, |
+ this, |
+ device_id)); |
+} |
+ |
+void VideoCaptureHost::OnEncodingCapabilitiesFound( |
+ int device_id, |
+ const media::VideoEncodingCapabilities& capabilities) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&VideoCaptureHost::DoEncodingCapabilitiesFoundOnIOThread, |
+ this, device_id, capabilities)); |
+} |
+ |
+void VideoCaptureHost::DoEncodingCapabilitiesFoundOnIOThread( |
+ int device_id, |
+ const media::VideoEncodingCapabilities& capabilities) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ Send(new EncodedVideoCaptureMsg_CapabilitiesAvailable(device_id, |
+ capabilities)); |
+} |
+ |
+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.session_id = session_id; |
+ |
+ VideoCaptureControllerID controller_id(device_id); |
+ DCHECK(entries_.find(controller_id) == entries_.end()); |
piman
2013/06/19 18:33:51
This data comes from the untrusted renderer.
This
sheu
2013/08/22 22:40:31
Done. Fixed also for OnStartCapture.
|
+ 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)); |