summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/resources/video_resource_updater.cc4
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc8
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.h2
-rw-r--r--content/browser/renderer_host/media/video_capture_controller_unittest.cc22
-rw-r--r--content/browser/renderer_host/media/video_capture_host.cc9
-rw-r--r--content/browser/renderer_host/media/video_capture_host.h4
-rw-r--r--content/browser/renderer_host/media/video_capture_host_unittest.cc7
-rw-r--r--content/common/media/video_capture_messages.h2
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc9
-rw-r--r--content/renderer/media/rtc_video_decoder.cc6
-rw-r--r--content/renderer/media/rtc_video_decoder.h6
-rw-r--r--content/renderer/media/video_capture_impl.cc23
-rw-r--r--content/renderer/media/video_capture_impl.h2
-rw-r--r--content/renderer/media/video_capture_impl_unittest.cc2
-rw-r--r--content/renderer/media/video_capture_message_filter.cc9
-rw-r--r--content/renderer/media/webmediaplayer_impl.cc3
-rw-r--r--media/base/video_frame.cc74
-rw-r--r--media/base/video_frame.h20
-rw-r--r--media/base/video_frame_unittest.cc67
-rw-r--r--media/filters/gpu_video_decoder.cc6
-rw-r--r--media/filters/gpu_video_decoder.h2
21 files changed, 185 insertions, 102 deletions
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 2000a13..75a2adb 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -282,7 +282,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
static void ReturnTexture(const scoped_refptr<media::VideoFrame>& frame,
uint32 sync_point,
bool lost_resource) {
- frame->mailbox_holder()->sync_point = sync_point;
+ frame->AppendReleaseSyncPoint(sync_point);
}
VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
@@ -296,7 +296,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
if (!context_provider_)
return VideoFrameExternalResources();
- gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
+ const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
VideoFrameExternalResources external_resources;
switch (mailbox_holder->texture_target) {
case GL_TEXTURE_2D:
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index fb1ff7a..9c70806 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -251,7 +251,7 @@ void VideoCaptureController::ReturnBuffer(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
int buffer_id,
- uint32 sync_point) {
+ const std::vector<uint32>& sync_points) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ControllerClient* client = FindClient(id, event_handler, controller_clients_);
@@ -267,8 +267,10 @@ void VideoCaptureController::ReturnBuffer(
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;
+ if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) {
+ for (size_t i = 0; i < sync_points.size(); i++)
+ frame->AppendReleaseSyncPoint(sync_points[i]);
+ }
buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
}
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h
index c0c3bed..9b82870 100644
--- a/content/browser/renderer_host/media/video_capture_controller.h
+++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -105,7 +105,7 @@ class CONTENT_EXPORT VideoCaptureController {
void ReturnBuffer(const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
int buffer_id,
- uint32 sync_point);
+ const std::vector<uint32>& sync_points);
const media::VideoCaptureFormat& GetVideoCaptureFormat() const;
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index 5fbb515..f650397 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -70,7 +70,7 @@ class MockVideoCaptureControllerEventHandler
id,
this,
buffer_id,
- 0));
+ std::vector<uint32>()));
}
virtual void OnMailboxBufferReady(const VideoCaptureControllerID& id,
int buffer_id,
@@ -79,7 +79,8 @@ class MockVideoCaptureControllerEventHandler
base::TimeTicks timestamp) OVERRIDE {
DoMailboxBufferReady(id);
// Use a very different syncpoint value when returning a new syncpoint.
- const uint32 new_sync_point = ~mailbox_holder.sync_point;
+ std::vector<uint32> release_sync_points;
+ release_sync_points.push_back(~mailbox_holder.sync_point);
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&VideoCaptureController::ReturnBuffer,
@@ -87,7 +88,7 @@ class MockVideoCaptureControllerEventHandler
id,
this,
buffer_id,
- new_sync_point));
+ release_sync_points));
}
virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE {
DoEnded(id);
@@ -262,9 +263,11 @@ TEST_F(VideoCaptureControllerTest, AddAndRemoveClients) {
<< "Client count should return to zero after all clients are gone.";
}
-static void CacheSyncPoint(uint32* sync_value,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
- *sync_value = mailbox_holder->sync_point;
+static void CacheSyncPoint(std::vector<uint32>* called_release_sync_points,
+ const std::vector<uint32>& release_sync_points) {
+ DCHECK(called_release_sync_points->empty());
+ called_release_sync_points->assign(release_sync_points.begin(),
+ release_sync_points.end());
}
// This test will connect and disconnect several clients while simulating an
@@ -481,7 +484,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
buffer = NULL;
}
std::vector<uint32> mailbox_syncpoints(mailbox_buffers);
- std::vector<uint32> mailbox_syncpoints_new(mailbox_buffers);
+ std::vector<std::vector<uint32> > release_syncpoint_vectors(mailbox_buffers);
for (int i = 0; i < mailbox_buffers; ++i) {
buffer = device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE,
gfx::Size(0, 0));
@@ -496,7 +499,7 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
buffer,
make_scoped_ptr(new gpu::MailboxHolder(
gpu::Mailbox(), 0, mailbox_syncpoints[i])),
- base::Bind(&CacheSyncPoint, &mailbox_syncpoints_new[i]),
+ base::Bind(&CacheSyncPoint, &release_syncpoint_vectors[i]),
capture_resolution),
base::TimeTicks());
buffer = NULL;
@@ -513,7 +516,8 @@ TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
base::RunLoop().RunUntilIdle();
for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) {
// See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady()
- ASSERT_EQ(mailbox_syncpoints[i], ~mailbox_syncpoints_new[i]);
+ ASSERT_EQ(1u, release_syncpoint_vectors[i].size());
+ ASSERT_EQ(mailbox_syncpoints[i], ~release_syncpoint_vectors[i][0]);
}
Mock::VerifyAndClearExpectations(client_b_.get());
}
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc
index 43bc404..14ab5d4 100644
--- a/content/browser/renderer_host/media/video_capture_host.cc
+++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -295,9 +295,10 @@ void VideoCaptureHost::OnPauseCapture(int device_id) {
Send(new VideoCaptureMsg_StateChanged(device_id, VIDEO_CAPTURE_STATE_ERROR));
}
-void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id,
- int buffer_id,
- uint32 sync_point) {
+void VideoCaptureHost::OnReceiveEmptyBuffer(
+ int device_id,
+ int buffer_id,
+ const std::vector<uint32>& sync_points) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
VideoCaptureControllerID controller_id(device_id);
@@ -305,7 +306,7 @@ void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id,
if (it != entries_.end()) {
const base::WeakPtr<VideoCaptureController>& controller = it->second;
if (controller)
- controller->ReturnBuffer(controller_id, this, buffer_id, sync_point);
+ controller->ReturnBuffer(controller_id, this, buffer_id, sync_points);
}
}
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h
index 89dd1d6..25d6947 100644
--- a/content/browser/renderer_host/media/video_capture_host.h
+++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -125,7 +125,9 @@ class CONTENT_EXPORT VideoCaptureHost
// IPC message: Receive an empty buffer from renderer. Send it to device
// referenced by |device_id|.
- void OnReceiveEmptyBuffer(int device_id, int buffer_id, uint32 sync_point);
+ void OnReceiveEmptyBuffer(int device_id,
+ int buffer_id,
+ const std::vector<uint32>& sync_points);
// IPC message: Get supported formats referenced by |capture_session_id|.
// |device_id| is needed for message back-routing purposes.
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc
index 48a3563..171d300 100644
--- a/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -151,7 +151,7 @@ class MockVideoCaptureHost : public VideoCaptureHost {
void ReturnReceivedDibs(int device_id) {
int handle = GetReceivedDib();
while (handle) {
- this->OnReceiveEmptyBuffer(device_id, handle, 0);
+ this->OnReceiveEmptyBuffer(device_id, handle, std::vector<uint32>());
handle = GetReceivedDib();
}
}
@@ -239,7 +239,8 @@ class MockVideoCaptureHost : public VideoCaptureHost {
OnBufferFilled(device_id, buffer_id, frame_format, timestamp);
if (return_buffers_) {
- VideoCaptureHost::OnReceiveEmptyBuffer(device_id, buffer_id, 0);
+ VideoCaptureHost::OnReceiveEmptyBuffer(
+ device_id, buffer_id, std::vector<uint32>());
}
}
@@ -252,7 +253,7 @@ class MockVideoCaptureHost : public VideoCaptureHost {
device_id, buffer_id, mailbox_holder, format, timestamp);
if (return_buffers_) {
VideoCaptureHost::OnReceiveEmptyBuffer(
- device_id, buffer_id, mailbox_holder.sync_point);
+ device_id, buffer_id, std::vector<uint32>());
}
}
diff --git a/content/common/media/video_capture_messages.h b/content/common/media/video_capture_messages.h
index abfc46c..c3970df 100644
--- a/content/common/media/video_capture_messages.h
+++ b/content/common/media/video_capture_messages.h
@@ -92,7 +92,7 @@ IPC_MESSAGE_CONTROL1(VideoCaptureHostMsg_Stop,
IPC_MESSAGE_CONTROL3(VideoCaptureHostMsg_BufferReady,
int /* device_id */,
int /* buffer_id */,
- uint32 /* syncpoint */)
+ std::vector<uint32> /* syncpoints */)
// Get the formats supported by a device referenced by |capture_session_id|.
IPC_MESSAGE_CONTROL2(VideoCaptureHostMsg_GetDeviceSupportedFormats,
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index a725840..c8c8ae4 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -71,10 +71,10 @@ const char* kMediaEme = "Media.EME.";
void OnReleaseTexture(
const scoped_refptr<content::StreamTextureFactory>& factories,
uint32 texture_id,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
+ const std::vector<uint32>& release_sync_points) {
GLES2Interface* gl = factories->ContextGL();
- if (mailbox_holder->sync_point)
- gl->WaitSyncPointCHROMIUM(mailbox_holder->sync_point);
+ for (size_t i = 0; i < release_sync_points.size(); i++)
+ gl->WaitSyncPointCHROMIUM(release_sync_points[i]);
gl->DeleteTextures(1, &texture_id);
}
} // namespace
@@ -468,7 +468,7 @@ bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
if (!video_frame ||
video_frame->format() != media::VideoFrame::NATIVE_TEXTURE)
return false;
- gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
+ const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
DCHECK((!is_remote_ &&
mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) ||
(is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D));
@@ -516,6 +516,7 @@ bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
web_graphics_context->bindTexture(GL_TEXTURE_2D, texture);
web_graphics_context->deleteTexture(source_texture);
web_graphics_context->flush();
+ video_frame->AppendReleaseSyncPoint(web_graphics_context->insertSyncPoint());
return true;
}
diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc
index 81ca813..3987767 100644
--- a/content/renderer/media/rtc_video_decoder.cc
+++ b/content/renderer/media/rtc_video_decoder.cc
@@ -639,9 +639,11 @@ void RTCVideoDecoder::ReleaseMailbox(
const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
int64 picture_buffer_id,
uint32 texture_id,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
+ const std::vector<uint32>& release_sync_points) {
DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread());
- factories->WaitSyncPoint(mailbox_holder->sync_point);
+
+ for (size_t i = 0; i < release_sync_points.size(); i++)
+ factories->WaitSyncPoint(release_sync_points[i]);
if (decoder) {
decoder->ReusePictureBuffer(picture_buffer_id);
diff --git a/content/renderer/media/rtc_video_decoder.h b/content/renderer/media/rtc_video_decoder.h
index e0070b7..d1a04e5 100644
--- a/content/renderer/media/rtc_video_decoder.h
+++ b/content/renderer/media/rtc_video_decoder.h
@@ -28,10 +28,6 @@ class WaitableEvent;
class MessageLoopProxy;
};
-namespace gpu {
-struct MailboxHolder;
-}
-
namespace media {
class DecoderBuffer;
class GpuVideoAcceleratorFactories;
@@ -156,7 +152,7 @@ class CONTENT_EXPORT RTCVideoDecoder
const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
int64 picture_buffer_id,
uint32 texture_id,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder);
+ const std::vector<uint32>& release_sync_points);
// Tells VDA that a picture buffer can be recycled.
void ReusePictureBuffer(int64 picture_buffer_id);
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index bda203a..465c9fe 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -214,7 +214,8 @@ void VideoCaptureImpl::OnBufferReceived(int buffer_id,
DCHECK_EQ(format.pixel_format, media::PIXEL_FORMAT_I420);
if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
- Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0));
+ Send(new VideoCaptureHostMsg_BufferReady(
+ device_id_, buffer_id, std::vector<uint32>()));
return;
}
@@ -242,12 +243,12 @@ void VideoCaptureImpl::OnBufferReceived(int buffer_id,
buffer->buffer_size,
buffer->buffer->handle(),
timestamp - first_frame_timestamp_,
- media::BindToCurrentLoop(base::Bind(
- &VideoCaptureImpl::OnClientBufferFinished,
- weak_factory_.GetWeakPtr(),
- buffer_id,
- buffer,
- base::Passed(scoped_ptr<gpu::MailboxHolder>().Pass()))));
+ media::BindToCurrentLoop(
+ base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
+ weak_factory_.GetWeakPtr(),
+ buffer_id,
+ buffer,
+ std::vector<uint32>())));
for (ClientInfoMap::iterator it = clients_.begin(); it != clients_.end();
++it) {
@@ -266,7 +267,7 @@ void VideoCaptureImpl::OnMailboxBufferReceived(
if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
Send(new VideoCaptureHostMsg_BufferReady(
- device_id_, buffer_id, mailbox_holder.sync_point));
+ device_id_, buffer_id, std::vector<uint32>()));
return;
}
@@ -296,10 +297,10 @@ void VideoCaptureImpl::OnMailboxBufferReceived(
void VideoCaptureImpl::OnClientBufferFinished(
int buffer_id,
const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
+ const std::vector<uint32>& release_sync_points) {
DCHECK(thread_checker_.CalledOnValidThread());
- const uint32 sync_point = (mailbox_holder ? mailbox_holder->sync_point : 0);
- Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, sync_point));
+ Send(new VideoCaptureHostMsg_BufferReady(
+ device_id_, buffer_id, release_sync_points));
}
void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) {
diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h
index 66c393c..872bfd6 100644
--- a/content/renderer/media/video_capture_impl.h
+++ b/content/renderer/media/video_capture_impl.h
@@ -129,7 +129,7 @@ class CONTENT_EXPORT VideoCaptureImpl
// buffer.
void OnClientBufferFinished(int buffer_id,
const scoped_refptr<ClientBuffer>& buffer,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder);
+ const std::vector<uint32>& release_sync_points);
void StopDevice();
void RestartCapture();
diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc
index 13c71af..1f54b76 100644
--- a/content/renderer/media/video_capture_impl_unittest.cc
+++ b/content/renderer/media/video_capture_impl_unittest.cc
@@ -80,7 +80,7 @@ class VideoCaptureImplTest : public ::testing::Test {
void DeviceReceiveEmptyBuffer(int device_id,
int buffer_id,
- uint32 sync_point) {}
+ const std::vector<uint32>& sync_points) {}
void DeviceGetSupportedFormats(int device_id,
media::VideoCaptureSessionId session_id) {
diff --git a/content/renderer/media/video_capture_message_filter.cc b/content/renderer/media/video_capture_message_filter.cc
index 78d25e7..f58347b 100644
--- a/content/renderer/media/video_capture_message_filter.cc
+++ b/content/renderer/media/video_capture_message_filter.cc
@@ -114,7 +114,8 @@ void VideoCaptureMessageFilter::OnBufferCreated(
// Send the buffer back to Host in case it's waiting for all buffers
// to be returned.
base::SharedMemory::CloseHandle(handle);
- Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
+ Send(new VideoCaptureHostMsg_BufferReady(
+ device_id, buffer_id, std::vector<uint32>()));
return;
}
@@ -133,7 +134,8 @@ void VideoCaptureMessageFilter::OnBufferReceived(
// Send the buffer back to Host in case it's waiting for all buffers
// to be returned.
- Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
+ Send(new VideoCaptureHostMsg_BufferReady(
+ device_id, buffer_id, std::vector<uint32>()));
return;
}
@@ -154,7 +156,8 @@ void VideoCaptureMessageFilter::OnMailboxBufferReceived(
// Send the buffer back to Host in case it's waiting for all buffers
// to be returned.
- Send(new VideoCaptureHostMsg_BufferReady(device_id, buffer_id, 0));
+ Send(new VideoCaptureHostMsg_BufferReady(
+ device_id, buffer_id, std::vector<uint32>()));
return;
}
diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc
index fa12b0f..75c1e7a 100644
--- a/content/renderer/media/webmediaplayer_impl.cc
+++ b/content/renderer/media/webmediaplayer_impl.cc
@@ -635,7 +635,7 @@ bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture(
if (video_frame->format() != media::VideoFrame::NATIVE_TEXTURE)
return false;
- gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
+ const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
if (mailbox_holder->texture_target != GL_TEXTURE_2D)
return false;
@@ -682,6 +682,7 @@ bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture(
web_graphics_context->deleteTexture(source_texture);
web_graphics_context->flush();
+ video_frame->AppendReleaseSyncPoint(web_graphics_context->insertSyncPoint());
return true;
}
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 8776665..3d01455 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -50,8 +50,14 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame(
return NULL;
}
DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
- scoped_refptr<VideoFrame> frame(new VideoFrame(
- format, new_coded_size, visible_rect, natural_size, timestamp, false));
+ scoped_refptr<VideoFrame> frame(
+ new VideoFrame(format,
+ new_coded_size,
+ visible_rect,
+ natural_size,
+ scoped_ptr<gpu::MailboxHolder>(),
+ timestamp,
+ false));
frame->AllocateYUV();
return frame;
}
@@ -145,9 +151,9 @@ scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture(
coded_size,
visible_rect,
natural_size,
+ mailbox_holder.Pass(),
timestamp,
false));
- frame->mailbox_holder_ = mailbox_holder.Pass();
frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb;
frame->read_pixels_cb_ = read_pixels_cb;
@@ -178,8 +184,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory(
switch (format) {
case I420: {
- scoped_refptr<VideoFrame> frame(new VideoFrame(
- format, coded_size, visible_rect, natural_size, timestamp, false));
+ scoped_refptr<VideoFrame> frame(
+ new VideoFrame(format,
+ coded_size,
+ visible_rect,
+ natural_size,
+ scoped_ptr<gpu::MailboxHolder>(),
+ timestamp,
+ false));
frame->shared_memory_handle_ = handle;
frame->strides_[kYPlane] = coded_size.width();
frame->strides_[kUPlane] = coded_size.width() / 2;
@@ -213,8 +225,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
return NULL;
- scoped_refptr<VideoFrame> frame(new VideoFrame(
- format, coded_size, visible_rect, natural_size, timestamp, false));
+ scoped_refptr<VideoFrame> frame(
+ new VideoFrame(format,
+ coded_size,
+ visible_rect,
+ natural_size,
+ scoped_ptr<gpu::MailboxHolder>(),
+ timestamp,
+ false));
frame->strides_[kYPlane] = y_stride;
frame->strides_[kUPlane] = u_stride;
frame->strides_[kVPlane] = v_stride;
@@ -236,9 +254,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame(
CHECK(frame->format() != NATIVE_TEXTURE);
DCHECK(frame->visible_rect().Contains(visible_rect));
- scoped_refptr<VideoFrame> wrapped_frame(new VideoFrame(
- frame->format(), frame->coded_size(), visible_rect, natural_size,
- frame->timestamp(), frame->end_of_stream()));
+ scoped_refptr<VideoFrame> wrapped_frame(
+ new VideoFrame(frame->format(),
+ frame->coded_size(),
+ visible_rect,
+ natural_size,
+ scoped_ptr<gpu::MailboxHolder>(),
+ frame->timestamp(),
+ frame->end_of_stream()));
for (size_t i = 0; i < NumPlanes(frame->format()); ++i) {
wrapped_frame->strides_[i] = frame->stride(i);
@@ -255,6 +278,7 @@ scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() {
gfx::Size(),
gfx::Rect(),
gfx::Size(),
+ scoped_ptr<gpu::MailboxHolder>(),
kNoTimestamp(),
true);
}
@@ -290,8 +314,14 @@ scoped_refptr<VideoFrame> VideoFrame::CreateBlackFrame(const gfx::Size& size) {
scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame(
const gfx::Size& size) {
DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size));
- scoped_refptr<VideoFrame> frame(new VideoFrame(
- VideoFrame::HOLE, size, gfx::Rect(size), size, base::TimeDelta(), false));
+ scoped_refptr<VideoFrame> frame(
+ new VideoFrame(VideoFrame::HOLE,
+ size,
+ gfx::Rect(size),
+ size,
+ scoped_ptr<gpu::MailboxHolder>(),
+ base::TimeDelta(),
+ false));
return frame;
}
#endif // defined(VIDEO_HOLE)
@@ -453,12 +483,14 @@ VideoFrame::VideoFrame(VideoFrame::Format format,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
+ scoped_ptr<gpu::MailboxHolder> mailbox_holder,
base::TimeDelta timestamp,
bool end_of_stream)
: format_(format),
coded_size_(coded_size),
visible_rect_(visible_rect),
natural_size_(natural_size),
+ mailbox_holder_(mailbox_holder.Pass()),
shared_memory_handle_(base::SharedMemory::NULLHandle()),
timestamp_(timestamp),
end_of_stream_(end_of_stream) {
@@ -470,8 +502,12 @@ VideoFrame::VideoFrame(VideoFrame::Format format,
VideoFrame::~VideoFrame() {
if (!mailbox_holder_release_cb_.is_null()) {
- base::ResetAndReturn(&mailbox_holder_release_cb_)
- .Run(mailbox_holder_.Pass());
+ std::vector<uint32> release_sync_points;
+ {
+ base::AutoLock locker(release_sync_point_lock_);
+ release_sync_points_.swap(release_sync_points);
+ }
+ base::ResetAndReturn(&mailbox_holder_release_cb_).Run(release_sync_points);
}
if (!no_longer_needed_cb_.is_null())
base::ResetAndReturn(&no_longer_needed_cb_).Run();
@@ -543,7 +579,7 @@ uint8* VideoFrame::data(size_t plane) const {
return data_[plane];
}
-gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
+const gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
DCHECK_EQ(format_, NATIVE_TEXTURE);
return mailbox_holder_.get();
}
@@ -552,6 +588,14 @@ base::SharedMemoryHandle VideoFrame::shared_memory_handle() const {
return shared_memory_handle_;
}
+void VideoFrame::AppendReleaseSyncPoint(uint32 sync_point) {
+ DCHECK_EQ(format_, NATIVE_TEXTURE);
+ if (!sync_point)
+ return;
+ base::AutoLock locker(release_sync_point_lock_);
+ release_sync_points_.push_back(sync_point);
+}
+
void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
for (int plane = 0; plane < kMaxPlanes; ++plane) {
if (!IsValidPlane(plane))
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 8106a27..024cb4c 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -5,9 +5,12 @@
#ifndef MEDIA_BASE_VIDEO_FRAME_H_
#define MEDIA_BASE_VIDEO_FRAME_H_
+#include <vector>
+
#include "base/callback.h"
#include "base/md5.h"
#include "base/memory/shared_memory.h"
+#include "base/synchronization/lock.h"
#include "media/base/buffers.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -80,7 +83,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// CB to be called on the mailbox backing this frame when the frame is
// destroyed.
- typedef base::Callback<void(scoped_ptr<gpu::MailboxHolder>)> ReleaseMailboxCB;
+ typedef base::Callback<void(const std::vector<uint32>&)> ReleaseMailboxCB;
// Wraps a native texture of the given parameters with a VideoFrame. The
// backing of the VideoFrame is held in the mailbox held by |mailbox_holder|,
@@ -204,7 +207,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// Returns the mailbox holder of the native texture wrapped by this frame.
// Only valid to call if this is a NATIVE_TEXTURE frame. Before using the
// mailbox, the caller must wait for the included sync point.
- gpu::MailboxHolder* mailbox_holder() const;
+ const gpu::MailboxHolder* mailbox_holder() const;
// Returns the shared-memory handle, if present
base::SharedMemoryHandle shared_memory_handle() const;
@@ -219,6 +222,13 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
timestamp_ = timestamp;
}
+ // Append |sync_point| into |release_sync_points_| which will be passed to
+ // the video decoder when |mailbox_holder_release_cb_| is called so that
+ // the video decoder waits for the sync points before reusing the mailbox.
+ // Multiple clients can append multiple sync points on one frame.
+ // This method is thread safe. Both blink and compositor threads can call it.
+ void AppendReleaseSyncPoint(uint32 sync_point);
+
// Used to keep a running hash of seen frames. Expects an initialized MD5
// context. Calls MD5Update with the context and the contents of the frame.
void HashFrameForTesting(base::MD5Context* context);
@@ -230,6 +240,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
+ scoped_ptr<gpu::MailboxHolder> mailbox_holder,
base::TimeDelta timestamp,
bool end_of_stream);
virtual ~VideoFrame();
@@ -267,7 +278,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
uint8* data_[kMaxPlanes];
// Native texture mailbox, if this is a NATIVE_TEXTURE frame.
- scoped_ptr<gpu::MailboxHolder> mailbox_holder_;
+ const scoped_ptr<gpu::MailboxHolder> mailbox_holder_;
ReleaseMailboxCB mailbox_holder_release_cb_;
ReadPixelsCB read_pixels_cb_;
@@ -278,6 +289,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
base::TimeDelta timestamp_;
+ base::Lock release_sync_point_lock_;
+ std::vector<uint32> release_sync_points_;
+
const bool end_of_stream_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame);
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index 8e7ce8f..618d68f 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -240,63 +240,72 @@ TEST(VideoFrame, CheckFrameExtents) {
ExpectFrameExtents(VideoFrame::YV16, "cce408a044b212db42a10dfec304b3ef");
}
-static void TextureCallback(uint32* called_sync_point,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
- *called_sync_point = mailbox_holder->sync_point;
+static void TextureCallback(std::vector<uint32>* called_sync_point,
+ const std::vector<uint32>& release_sync_points) {
+ called_sync_point->assign(release_sync_points.begin(),
+ release_sync_points.end());
}
// Verify the gpu::MailboxHolder::ReleaseCallback is called when VideoFrame is
-// destroyed with the original sync point.
+// destroyed with the default release sync points.
TEST(VideoFrame, TextureNoLongerNeededCallbackIsCalled) {
- uint32 sync_point = 7;
- uint32 called_sync_point = 0;
+ std::vector<uint32> called_sync_points;
+ called_sync_points.push_back(1);
{
scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTexture(
- make_scoped_ptr(new gpu::MailboxHolder(gpu::Mailbox(), 5, sync_point)),
- base::Bind(&TextureCallback, &called_sync_point),
- gfx::Size(10, 10), // coded_size
- gfx::Rect(10, 10), // visible_rect
- gfx::Size(10, 10), // natural_size
- base::TimeDelta(), // timestamp
- base::Callback<void(const SkBitmap&)>()); // read_pixels_cb
-
- EXPECT_EQ(0u, called_sync_point);
+ make_scoped_ptr(
+ new gpu::MailboxHolder(gpu::Mailbox(), 5, 0 /* sync_point */)),
+ base::Bind(&TextureCallback, &called_sync_points),
+ gfx::Size(10, 10), // coded_size
+ gfx::Rect(10, 10), // visible_rect
+ gfx::Size(10, 10), // natural_size
+ base::TimeDelta(), // timestamp
+ VideoFrame::ReadPixelsCB()); // read_pixels_cb
+
+ EXPECT_EQ(1u, called_sync_points.size());
}
- EXPECT_EQ(sync_point, called_sync_point);
+ EXPECT_TRUE(called_sync_points.empty());
}
// Verify the gpu::MailboxHolder::ReleaseCallback is called when VideoFrame is
-// destroyed with the new sync point, when the mailbox is accessed by a caller.
+// destroyed with the release sync points, which was updated by clients.
+// (i.e. the compositor, webgl).
TEST(VideoFrame, TextureNoLongerNeededCallbackAfterTakingAndReleasingMailbox) {
- uint32 called_sync_point = 0;
+ std::vector<uint32> called_sync_points;
gpu::Mailbox mailbox;
mailbox.name[0] = 50;
uint32 sync_point = 7;
uint32 target = 9;
+ std::vector<uint32> release_sync_points;
+ release_sync_points.push_back(1);
+ release_sync_points.push_back(2);
+ release_sync_points.push_back(3);
{
scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTexture(
make_scoped_ptr(new gpu::MailboxHolder(mailbox, target, sync_point)),
- base::Bind(&TextureCallback, &called_sync_point),
- gfx::Size(10, 10), // coded_size
- gfx::Rect(10, 10), // visible_rect
- gfx::Size(10, 10), // natural_size
- base::TimeDelta(), // timestamp
- base::Callback<void(const SkBitmap&)>()); // read_pixels_cb
+ base::Bind(&TextureCallback, &called_sync_points),
+ gfx::Size(10, 10), // coded_size
+ gfx::Rect(10, 10), // visible_rect
+ gfx::Size(10, 10), // natural_size
+ base::TimeDelta(), // timestamp
+ VideoFrame::ReadPixelsCB()); // read_pixels_cb
+ EXPECT_TRUE(called_sync_points.empty());
- gpu::MailboxHolder* mailbox_holder = frame->mailbox_holder();
+ const gpu::MailboxHolder* mailbox_holder = frame->mailbox_holder();
EXPECT_EQ(mailbox.name[0], mailbox_holder->mailbox.name[0]);
EXPECT_EQ(target, mailbox_holder->texture_target);
EXPECT_EQ(sync_point, mailbox_holder->sync_point);
- // Finish using the mailbox_holder and drop our reference.
- sync_point = 10;
- mailbox_holder->sync_point = sync_point;
+ frame->AppendReleaseSyncPoint(release_sync_points[0]);
+ frame->AppendReleaseSyncPoint(release_sync_points[1]);
+ frame->AppendReleaseSyncPoint(release_sync_points[2]);
+ EXPECT_EQ(sync_point, mailbox_holder->sync_point);
}
- EXPECT_EQ(sync_point, called_sync_point);
+ EXPECT_EQ(release_sync_points, called_sync_points);
}
} // namespace media
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc
index 392448d6..7a179e3 100644
--- a/media/filters/gpu_video_decoder.cc
+++ b/media/filters/gpu_video_decoder.cc
@@ -501,9 +501,11 @@ void GpuVideoDecoder::ReleaseMailbox(
const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
int64 picture_buffer_id,
uint32 texture_id,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
+ const std::vector<uint32>& release_sync_points) {
DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread());
- factories->WaitSyncPoint(mailbox_holder->sync_point);
+
+ for (size_t i = 0; i < release_sync_points.size(); i++)
+ factories->WaitSyncPoint(release_sync_points[i]);
if (decoder) {
decoder->ReusePictureBuffer(picture_buffer_id);
diff --git a/media/filters/gpu_video_decoder.h b/media/filters/gpu_video_decoder.h
index e8f5f75..1d905cd 100644
--- a/media/filters/gpu_video_decoder.h
+++ b/media/filters/gpu_video_decoder.h
@@ -108,7 +108,7 @@ class MEDIA_EXPORT GpuVideoDecoder
const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
int64 picture_buffer_id,
uint32 texture_id,
- scoped_ptr<gpu::MailboxHolder> mailbox_holder);
+ const std::vector<uint32>& release_sync_points);
// Indicate the picture buffer can be reused by the decoder.
void ReusePictureBuffer(int64 picture_buffer_id);