diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-11-21 14:09:57 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-11-29 15:14:36 +0100 |
commit | eb32ba6f51d0c21d58cd7d89785285ff8fa64624 (patch) | |
tree | 2c7c940e1dbee81b89d935626110816b494aa32c /chromium/content/renderer | |
parent | 9427c1a0222ebd67efef1a2c7990a0fa5c9aac84 (diff) | |
download | qtwebengine-chromium-eb32ba6f51d0c21d58cd7d89785285ff8fa64624.tar.gz |
Update chromium to branch 1599.
Change-Id: I04e775a946a208bb4500d3b722bcb05c82b9d7cb
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/content/renderer')
46 files changed, 497 insertions, 1290 deletions
diff --git a/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc b/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc index abce9c8b069..7f602ff7887 100644 --- a/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc +++ b/chromium/content/renderer/accessibility/renderer_accessibility_complete.cc @@ -348,7 +348,8 @@ void RendererAccessibilityComplete::SendPendingAccessibilityNotifications() { AccessibilityHostMsg_NotificationParams notification_msg; notification_msg.notification_type = notification.notification_type; notification_msg.id = notification.id; - SerializeChangedNodes(obj, ¬ification_msg.nodes); + std::set<int> ids_serialized; + SerializeChangedNodes(obj, ¬ification_msg.nodes, &ids_serialized); notification_msgs.push_back(notification_msg); #ifndef NDEBUG @@ -419,7 +420,12 @@ RendererAccessibilityComplete::CreateBrowserTreeNode() { void RendererAccessibilityComplete::SerializeChangedNodes( const WebKit::WebAccessibilityObject& obj, - std::vector<AccessibilityNodeData>* dst) { + std::vector<AccessibilityNodeData>* dst, + std::set<int>* ids_serialized) { + if (ids_serialized->find(obj.axID()) != ids_serialized->end()) + return; + ids_serialized->insert(obj.axID()); + // This method has three responsibilities: // 1. Serialize |obj| into an AccessibilityNodeData, and append it to // the end of the |dst| vector to be send to the browser process. @@ -474,6 +480,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( WebAccessibilityObject parent_obj; while (parent) { parent_obj = document.accessibilityObjectFromID(parent->id); + if (!parent_obj.isDetached()) break; parent = parent->parent; @@ -483,7 +490,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( // so that the update that clears |child| from its old parent // occurs stricly before the update that adds |child| to its // new parent. - SerializeChangedNodes(parent_obj, dst); + SerializeChangedNodes(parent_obj, dst, ids_serialized); } } } @@ -556,7 +563,7 @@ void RendererAccessibilityComplete::SerializeChangedNodes( // Serialize all of the new children, recursively. for (size_t i = 0; i < children_to_serialize.size(); ++i) - SerializeChangedNodes(children_to_serialize[i], dst); + SerializeChangedNodes(children_to_serialize[i], dst, ids_serialized); } void RendererAccessibilityComplete::ClearBrowserTreeNode( diff --git a/chromium/content/renderer/accessibility/renderer_accessibility_complete.h b/chromium/content/renderer/accessibility/renderer_accessibility_complete.h index 82fe4f81d44..4abdfb51311 100644 --- a/chromium/content/renderer/accessibility/renderer_accessibility_complete.h +++ b/chromium/content/renderer/accessibility/renderer_accessibility_complete.h @@ -5,6 +5,7 @@ #ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ #define CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ +#include <set> #include <vector> #include "base/containers/hash_tables.h" @@ -81,8 +82,11 @@ class CONTENT_EXPORT RendererAccessibilityComplete // Serialize the given accessibility object |obj| and append it to // |dst|, and then recursively also serialize any *new* children of // |obj|, based on what object ids we know the browser already has. + // The set of ids serialized is added to |ids_serialized|, and any + // ids previously in that set are not serialized again. void SerializeChangedNodes(const WebKit::WebAccessibilityObject& obj, - std::vector<AccessibilityNodeData>* dst); + std::vector<AccessibilityNodeData>* dst, + std::set<int>* ids_serialized); // Clear the given node and recursively delete all of its descendants // from the browser tree. (Does not delete |browser_node|). diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc index cf0bdcc54b9..03fffc15ed5 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc @@ -71,7 +71,6 @@ BrowserPlugin::BrowserPlugin( WebKit::WebFrame* frame, const WebPluginParams& params) : guest_instance_id_(browser_plugin::kInstanceIDNone), - attached_(false), render_view_(render_view->AsWeakPtr()), render_view_routing_id_(render_view->GetRoutingID()), container_(NULL), @@ -86,6 +85,7 @@ BrowserPlugin::BrowserPlugin( content_window_routing_id_(MSG_ROUTING_NONE), plugin_focused_(false), visible_(true), + size_changed_in_flight_(false), before_first_navigation_(true), mouse_locked_(false), browser_plugin_manager_(render_view->GetBrowserPluginManager()), @@ -330,6 +330,21 @@ void BrowserPlugin::UpdateGuestAutoSizeState(bool current_auto_size) { resize_guest_params)); } +void BrowserPlugin::SizeChangedDueToAutoSize(const gfx::Size& old_view_size) { + size_changed_in_flight_ = false; + + std::map<std::string, base::Value*> props; + props[browser_plugin::kOldHeight] = + new base::FundamentalValue(old_view_size.height()); + props[browser_plugin::kOldWidth] = + new base::FundamentalValue(old_view_size.width()); + props[browser_plugin::kNewHeight] = + new base::FundamentalValue(last_view_size_.height()); + props[browser_plugin::kNewWidth] = + new base::FundamentalValue(last_view_size_.width()); + TriggerEvent(browser_plugin::kEventSizeChanged, &props); +} + // static bool BrowserPlugin::UsesDamageBuffer( const BrowserPluginMsg_UpdateRect_Params& params) { @@ -394,7 +409,6 @@ void BrowserPlugin::OnAttachACK( params.storage_partition_id; UpdateDOMAttribute(browser_plugin::kAttributePartition, partition_name); } - attached_ = true; } void BrowserPlugin::OnBuffersSwapped( @@ -501,9 +515,8 @@ void BrowserPlugin::OnUpdateRect( // In HW mode, we need to do it here so we can continue sending // resize messages when needed. if (params.is_resize_ack || - (!params.needs_ack && (auto_size || auto_size_ack_pending_))) { + (!params.needs_ack && (auto_size || auto_size_ack_pending_))) resize_ack_received_ = true; - } auto_size_ack_pending_ = false; @@ -546,7 +559,24 @@ void BrowserPlugin::OnUpdateRect( if (auto_size && (params.view_size != last_view_size_)) { if (backing_store_) backing_store_->Clear(SK_ColorWHITE); + gfx::Size old_view_size = last_view_size_; last_view_size_ = params.view_size; + // Schedule a SizeChanged instead of calling it directly to ensure that + // the backing store has been updated before the developer attempts to + // resize to avoid flicker. |size_changed_in_flight_| acts as a form of + // flow control for SizeChanged events. If the guest's view size is changing + // rapidly before a SizeChanged event fires, then we avoid scheduling + // another SizeChanged event. SizeChanged reads the new size from + // |last_view_size_| so we can be sure that it always fires an event + // with the last seen view size. + if (container_ && !size_changed_in_flight_) { + size_changed_in_flight_ = true; + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&BrowserPlugin::SizeChangedDueToAutoSize, + base::Unretained(this), + old_view_size)); + } } if (UsesDamageBuffer(params)) { @@ -1059,7 +1089,7 @@ void BrowserPlugin::updateGeometry( int old_width = width(); int old_height = height(); plugin_rect_ = window_rect; - if (!attached()) + if (!HasGuestInstanceID()) return; // In AutoSize mode, guests don't care when the BrowserPlugin container is diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h index 89481196bec..d18906a573d 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin.h +++ b/chromium/content/renderer/browser_plugin/browser_plugin.h @@ -40,7 +40,6 @@ class CONTENT_EXPORT BrowserPlugin : RenderViewImpl* render_view() const { return render_view_.get(); } int render_view_routing_id() const { return render_view_routing_id_; } int guest_instance_id() const { return guest_instance_id_; } - bool attached() const { return attached_; } static BrowserPlugin* FromContainer(WebKit::WebPluginContainer* container); @@ -271,6 +270,9 @@ class CONTENT_EXPORT BrowserPlugin : // Informs the guest of an updated autosize state. void UpdateGuestAutoSizeState(bool current_auto_size); + // Informs the BrowserPlugin that guest has changed its size in autosize mode. + void SizeChangedDueToAutoSize(const gfx::Size& old_view_size); + // Indicates whether a damage buffer was used by the guest process for the // provided |params|. static bool UsesDamageBuffer( @@ -310,9 +312,6 @@ class CONTENT_EXPORT BrowserPlugin : // This is the browser-process-allocated instance ID that uniquely identifies // a guest WebContents. int guest_instance_id_; - // This indicates whether this BrowserPlugin has been attached to a - // WebContents. - bool attached_; base::WeakPtr<RenderViewImpl> render_view_; // We cache the |render_view_|'s routing ID because we need it on destruction. // If the |render_view_| is destroyed before the BrowserPlugin is destroyed @@ -344,6 +343,7 @@ class CONTENT_EXPORT BrowserPlugin : WebCursor cursor_; gfx::Size last_view_size_; + bool size_changed_in_flight_; bool before_first_navigation_; bool mouse_locked_; diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc b/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc index 26f00504e32..a1025580cbe 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin_bindings.cc @@ -286,6 +286,28 @@ class BrowserPluginBindingAttachWindowTo : public BrowserPluginMethodBinding { // Note: This is a method that is used internally by the <webview> shim only. // This should not be exposed to developers. +class BrowserPluginBindingGetGuestInstanceID : + public BrowserPluginMethodBinding { + public: + BrowserPluginBindingGetGuestInstanceID() + : BrowserPluginMethodBinding( + browser_plugin::kMethodGetGuestInstanceId, 0) { + } + + virtual bool Invoke(BrowserPluginBindings* bindings, + const NPVariant* args, + NPVariant* result) OVERRIDE { + int guest_instance_id = bindings->instance()->guest_instance_id(); + INT32_TO_NPVARIANT(guest_instance_id, *result); + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(BrowserPluginBindingGetGuestInstanceID); +}; + +// Note: This is a method that is used internally by the <webview> shim only. +// This should not be exposed to developers. class BrowserPluginBindingTrackObjectLifetime : public BrowserPluginMethodBinding { public: @@ -526,6 +548,7 @@ class BrowserPluginPropertyBindingName NPVariant* result) OVERRIDE { std::string name = bindings->instance()->GetNameAttribute(); return StringToNPVariant(name, result); + return true; } virtual bool SetProperty(BrowserPluginBindings* bindings, NPObject* np_obj, @@ -566,12 +589,10 @@ class BrowserPluginPropertyBindingPartition UpdateDOMAttribute(bindings, new_value); std::string error_message; if (!bindings->instance()->ParsePartitionAttribute(&error_message)) { - // Reset to old value on error. - UpdateDOMAttribute(bindings, old_value); - // Exceptions must be set as the last operation before returning to - // script. WebBindings::setException( np_obj, static_cast<const NPUTF8 *>(error_message.c_str())); + // Reset to old value on error. + UpdateDOMAttribute(bindings, old_value); return false; } } @@ -622,12 +643,10 @@ class BrowserPluginPropertyBindingSrc : public BrowserPluginPropertyBinding { UpdateDOMAttribute(bindings, new_value); std::string error_message; if (!bindings->instance()->ParseSrcAttribute(&error_message)) { - // Reset to old value on error. - UpdateDOMAttribute(bindings, old_value); - // Exceptions must be set as the last operation before returning to - // script. WebBindings::setException( np_obj, static_cast<const NPUTF8 *>(error_message.c_str())); + // Reset to old value on error. + UpdateDOMAttribute(bindings, old_value); return false; } } @@ -636,8 +655,6 @@ class BrowserPluginPropertyBindingSrc : public BrowserPluginPropertyBinding { virtual void RemoveProperty(BrowserPluginBindings* bindings, NPObject* np_obj) OVERRIDE { std::string old_value = bindings->instance()->GetSrcAttribute(); - if (old_value.empty()) - return; // Remove the DOM attribute to trigger the mutation observer when it is // restored to its original value again. bindings->instance()->RemoveDOMAttribute(name()); @@ -668,6 +685,7 @@ BrowserPluginBindings::BrowserPluginBindings(BrowserPlugin* instance) method_bindings_.push_back(new BrowserPluginBindingAttach); method_bindings_.push_back(new BrowserPluginBindingAttachWindowTo); + method_bindings_.push_back(new BrowserPluginBindingGetGuestInstanceID); method_bindings_.push_back(new BrowserPluginBindingTrackObjectLifetime); property_bindings_.push_back(new BrowserPluginPropertyBindingAutoSize); diff --git a/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc index 693752c618a..1ad07e9845b 100644 --- a/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc +++ b/chromium/content/renderer/browser_plugin/browser_plugin_browsertest.cc @@ -172,13 +172,8 @@ MockBrowserPlugin* BrowserPluginTest::GetCurrentPluginWithAttachParams( msg, &iter, params)) return NULL; - MockBrowserPlugin* browser_plugin = static_cast<MockBrowserPlugin*>( + return static_cast<MockBrowserPlugin*>( browser_plugin_manager()->GetBrowserPlugin(instance_id)); - - BrowserPluginMsg_Attach_ACK_Params attach_ack_params; - browser_plugin->OnAttachACK(instance_id, attach_ack_params); - - return browser_plugin; } // This test verifies that an initial resize occurs when we instantiate the diff --git a/chromium/content/renderer/browser_plugin/mock_browser_plugin.h b/chromium/content/renderer/browser_plugin/mock_browser_plugin.h index acd001b64ca..ac12aa3015e 100644 --- a/chromium/content/renderer/browser_plugin/mock_browser_plugin.h +++ b/chromium/content/renderer/browser_plugin/mock_browser_plugin.h @@ -18,7 +18,6 @@ class MockBrowserPlugin : public BrowserPlugin { virtual ~MockBrowserPlugin(); // Allow poking at a few private members. - using BrowserPlugin::OnAttachACK; using BrowserPlugin::guest_crashed_; using BrowserPlugin::pending_damage_buffer_; using BrowserPlugin::damage_buffer_sequence_id_; diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc index 65b451159f0..a274d0d8361 100644 --- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc @@ -16,6 +16,7 @@ #include "content/public/renderer/render_thread.h" #include "content/renderer/gpu/render_widget_compositor.h" #include "content/renderer/render_view_impl.h" +#include "content/renderer/rendering_benchmark.h" #include "content/renderer/skia_benchmarking_extension.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebImageCache.h" diff --git a/chromium/content/renderer/media/android/media_source_delegate.cc b/chromium/content/renderer/media/android/media_source_delegate.cc index 715d5207c4a..c13a4987fb7 100644 --- a/chromium/content/renderer/media/android/media_source_delegate.cc +++ b/chromium/content/renderer/media/android/media_source_delegate.cc @@ -37,6 +37,22 @@ const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff }; namespace content { +#define BIND_TO_RENDER_LOOP(function) \ + media::BindToLoop(main_loop_, \ + base::Bind(function, main_weak_this_.GetWeakPtr())) + +#define BIND_TO_RENDER_LOOP_1(function, arg1) \ + media::BindToLoop(main_loop_, \ + base::Bind(function, main_weak_this_.GetWeakPtr(), arg1)) + +#if defined(GOOGLE_TV) +#define DCHECK_BELONG_TO_MEDIA_LOOP() \ + DCHECK(media_loop_->BelongsToCurrentThread()) +#else +#define DCHECK_BELONG_TO_MEDIA_LOOP() \ + DCHECK(main_loop_->BelongsToCurrentThread()) +#endif + static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, const std::string& error) { media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); @@ -50,16 +66,15 @@ MediaSourceDelegate::MediaSourceDelegate( : main_weak_this_(this), media_weak_this_(this), main_loop_(base::MessageLoopProxy::current()), +#if defined(GOOGLE_TV) media_loop_(media_loop), - send_read_from_demuxer_ack_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendReadFromDemuxerAck, - main_weak_this_.GetWeakPtr()))), - send_seek_request_ack_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendSeekRequestAck, - main_weak_this_.GetWeakPtr()))), - send_demuxer_ready_cb_(media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::SendDemuxerReady, - main_weak_this_.GetWeakPtr()))), + send_read_from_demuxer_ack_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendReadFromDemuxerAck)), + send_seek_request_ack_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendSeekRequestAck)), + send_demuxer_ready_cb_( + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendDemuxerReady)), +#endif proxy_(proxy), player_id_(player_id), media_log_(media_log), @@ -102,16 +117,20 @@ void MediaSourceDelegate::Destroy() { if (chunk_demuxer_) chunk_demuxer_->Shutdown(); +#if defined(GOOGLE_TV) // |this| will be transfered to the callback StopDemuxer() and // OnDemuxerStopDone(). they own |this| and OnDemuxerStopDone() will delete // it when called. Hence using base::Unretained(this) is safe here. media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::StopDemuxer, base::Unretained(this))); +#else + StopDemuxer(); +#endif } void MediaSourceDelegate::StopDemuxer() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DCHECK(demuxer_); audio_stream_ = NULL; @@ -147,26 +166,26 @@ void MediaSourceDelegate::InitializeMediaSource( access_unit_size_ = kAccessUnitSizeForMediaSource; chunk_demuxer_.reset(new media::ChunkDemuxer( - media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::OnDemuxerOpened, - main_weak_this_.GetWeakPtr())), - media::BindToLoop(main_loop_, - base::Bind(&MediaSourceDelegate::OnNeedKey, - main_weak_this_.GetWeakPtr(), "")), + BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), + BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnNeedKey, ""), // WeakPtrs can only bind to methods without return values. base::Bind(&MediaSourceDelegate::OnAddTextTrack, base::Unretained(this)), base::Bind(&LogMediaSourceError, media_log_))); demuxer_ = chunk_demuxer_.get(); +#if defined(GOOGLE_TV) // |this| will be retained until StopDemuxer() is posted, so Unretained() is // safe here. media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::InitializeDemuxer, base::Unretained(this))); +#else + InitializeDemuxer(); +#endif } void MediaSourceDelegate::InitializeDemuxer() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); demuxer_->Initialize(this, base::Bind(&MediaSourceDelegate::OnDemuxerInitDone, media_weak_this_.GetWeakPtr())); } @@ -230,15 +249,19 @@ void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) { } SetSeeking(true); +#if defined(GOOGLE_TV) media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::SeekInternal, base::Unretained(this), time, seek_request_id)); +#else + SeekInternal(time, seek_request_id); +#endif } void MediaSourceDelegate::SeekInternal(base::TimeDelta time, unsigned request_id) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); demuxer_->Seek(time, base::Bind(&MediaSourceDelegate::OnDemuxerSeekDone, media_weak_this_.GetWeakPtr(), request_id)); } @@ -266,15 +289,19 @@ void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { DCHECK(main_loop_->BelongsToCurrentThread()); +#if defined(GOOGLE_TV) media_loop_->PostTask( FROM_HERE, base::Bind(&MediaSourceDelegate::OnReadFromDemuxerInternal, base::Unretained(this), type)); +#else + OnReadFromDemuxerInternal(type); +#endif } void MediaSourceDelegate::OnReadFromDemuxerInternal( media::DemuxerStream::Type type) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnReadFromDemuxer(" << type << ") : " << player_id_; if (IsSeeking()) return; // Drop the request during seeking. @@ -293,8 +320,7 @@ void MediaSourceDelegate::ReadFromDemuxerStream( media::DemuxerStream::Type type, scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params, size_t index) { - DCHECK(media_loop_->BelongsToCurrentThread()); - DCHECK(!IsSeeking()); + DCHECK_BELONG_TO_MEDIA_LOOP(); // DemuxerStream::Read() always returns the read callback asynchronously. DemuxerStream* stream = (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; @@ -309,7 +335,7 @@ void MediaSourceDelegate::OnBufferReady( size_t index, DemuxerStream::Status status, const scoped_refptr<media::DecoderBuffer>& buffer) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnBufferReady(" << index << ", " << status << ", " << ((!buffer || buffer->end_of_stream()) ? -1 : buffer->timestamp().InMilliseconds()) @@ -406,7 +432,11 @@ void MediaSourceDelegate::OnBufferReady( NOTREACHED(); } +#if defined(GOOGLE_TV) send_read_from_demuxer_ack_cb_.Run(params.Pass()); +#else + SendReadFromDemuxerAck(params.Pass()); +#endif } void MediaSourceDelegate::SendReadFromDemuxerAck( @@ -424,7 +454,7 @@ void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { } void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnDemuxerInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -457,7 +487,7 @@ void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { } void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "InitAudioDecryptingDemuxerStream() : " << player_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); @@ -470,7 +500,7 @@ void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { } void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "InitVideoDecryptingDemuxerStream() : " << player_id_; DCHECK(!set_decryptor_ready_cb_.is_null()); @@ -484,7 +514,7 @@ void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnAudioDecryptingDemuxerStreamInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -508,7 +538,7 @@ void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnVideoDecryptingDemuxerStreamInitDone(" << status << ") : " << player_id_; DCHECK(demuxer_); @@ -526,7 +556,7 @@ void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, media::PipelineStatus status) { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "OnDemuxerSeekDone(" << status << ") : " << player_id_; DCHECK(IsSeeking()); @@ -547,7 +577,7 @@ void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, } void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "ResetAudioDecryptingDemuxerStream() : " << player_id_; if (audio_decrypting_demuxer_stream_) { audio_decrypting_demuxer_stream_->Reset( @@ -559,12 +589,22 @@ void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { } void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "ResetVideoDecryptingDemuxerStream()"; +#if defined(GOOGLE_TV) if (video_decrypting_demuxer_stream_) video_decrypting_demuxer_stream_->Reset(send_seek_request_ack_cb_); else send_seek_request_ack_cb_.Run(); +#else + if (video_decrypting_demuxer_stream_) { + video_decrypting_demuxer_stream_->Reset( + base::Bind(&MediaSourceDelegate::SendSeekRequestAck, + main_weak_this_.GetWeakPtr())); + } else { + SendSeekRequestAck(); + } +#endif } void MediaSourceDelegate::SendSeekRequestAck() { @@ -583,23 +623,27 @@ void MediaSourceDelegate::OnDemuxerStopDone() { } void MediaSourceDelegate::OnMediaConfigRequest() { +#if defined(GOOGLE_TV) if (!media_loop_->BelongsToCurrentThread()) { media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::OnMediaConfigRequest, base::Unretained(this))); return; } +#endif if (CanNotifyDemuxerReady()) NotifyDemuxerReady(); } void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { +#if defined(GOOGLE_TV) if (!media_loop_->BelongsToCurrentThread()) { media_loop_->PostTask(FROM_HERE, base::Bind(&MediaSourceDelegate::NotifyKeyAdded, base::Unretained(this), key_system)); return; } +#endif DVLOG(1) << "NotifyKeyAdded() : " << player_id_; // TODO(kjyoun): Enhance logic to detect when to call NotifyDemuxerReady() // For now, we calls it when the first key is added. See @@ -615,7 +659,7 @@ void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { } bool MediaSourceDelegate::CanNotifyDemuxerReady() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); // This can happen when a key is added before the demuxer is initialized. // See NotifyKeyAdded(). // TODO(kjyoun): Remove NotifyDemxuerReady() call from NotifyKeyAdded() so @@ -629,7 +673,7 @@ bool MediaSourceDelegate::CanNotifyDemuxerReady() { } void MediaSourceDelegate::NotifyDemuxerReady() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); DVLOG(1) << "NotifyDemuxerReady() : " << player_id_; DCHECK(CanNotifyDemuxerReady()); @@ -656,7 +700,11 @@ void MediaSourceDelegate::NotifyDemuxerReady() { params->duration_ms = GetDurationMs(); params->key_system = HasEncryptedStream() ? key_system_ : ""; +#if defined(GOOGLE_TV) send_demuxer_ready_cb_.Run(params.Pass()); +#else + SendDemuxerReady(params.Pass()); +#endif } void MediaSourceDelegate::SendDemuxerReady( @@ -667,7 +715,7 @@ void MediaSourceDelegate::SendDemuxerReady( } int MediaSourceDelegate::GetDurationMs() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); if (!chunk_demuxer_) return -1; @@ -708,7 +756,7 @@ scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack( } bool MediaSourceDelegate::HasEncryptedStream() { - DCHECK(media_loop_->BelongsToCurrentThread()); + DCHECK_BELONG_TO_MEDIA_LOOP(); return (audio_stream_ && audio_stream_->audio_decoder_config().is_encrypted()) || (video_stream_ && diff --git a/chromium/content/renderer/media/android/media_source_delegate.h b/chromium/content/renderer/media/android/media_source_delegate.h index 8f359814e55..1c358d51d85 100644 --- a/chromium/content/renderer/media/android/media_source_delegate.h +++ b/chromium/content/renderer/media/android/media_source_delegate.h @@ -184,6 +184,7 @@ class MediaSourceDelegate : public media::DemuxerHost { // Message loop for main renderer thread. const scoped_refptr<base::MessageLoopProxy> main_loop_; +#if defined(GOOGLE_TV) // Message loop for the media thread. // When there is high load in the render thread, the reading from |demuxer_| // and its read-callback loops run very slowly. To improve the response time @@ -193,6 +194,7 @@ class MediaSourceDelegate : public media::DemuxerHost { ReadFromDemuxerAckCB send_read_from_demuxer_ack_cb_; base::Closure send_seek_request_ack_cb_; DemuxerReadyCB send_demuxer_ready_cb_; +#endif WebMediaPlayerProxyAndroid* proxy_; int player_id_; diff --git a/chromium/content/renderer/media/media_stream_dependency_factory.cc b/chromium/content/renderer/media/media_stream_dependency_factory.cc index b5adf1ed754..2d19ae035f2 100644 --- a/chromium/content/renderer/media/media_stream_dependency_factory.cc +++ b/chromium/content/renderer/media/media_stream_dependency_factory.cc @@ -16,7 +16,6 @@ #include "content/renderer/media/rtc_peer_connection_handler.h" #include "content/renderer/media/rtc_video_capturer.h" #include "content/renderer/media/rtc_video_decoder_factory.h" -#include "content/renderer/media/rtc_video_encoder_factory.h" #include "content/renderer/media/video_capture_impl_manager.h" #include "content/renderer/media/webaudio_capturer_source.h" #include "content/renderer/media/webrtc_audio_device_impl.h" @@ -28,7 +27,7 @@ #include "content/renderer/p2p/port_allocator.h" #include "content/renderer/render_thread_impl.h" #include "jingle/glue/thread_wrapper.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/WebKit/public/platform/WebMediaConstraints.h" #include "third_party/WebKit/public/platform/WebMediaStream.h" #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" @@ -489,32 +488,27 @@ bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { audio_device_ = new WebRtcAudioDeviceImpl(); scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; - scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - scoped_refptr<base::MessageLoopProxy> media_loop_proxy = - RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(); - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories = - RenderThreadImpl::current()->GetGpuFactories(media_loop_proxy); -#if !defined(GOOGLE_TV) - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWDecoding)) - if (gpu_factories) + if (cmd_line->HasSwitch(switches::kEnableWebRtcHWDecoding)) { + scoped_refptr<base::MessageLoopProxy> media_loop_proxy = + RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(); + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories = + RenderThreadImpl::current()->GetGpuFactories(media_loop_proxy); + if (gpu_factories.get() != NULL) decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories)); -#else + } +#if defined(GOOGLE_TV) // PeerConnectionFactory will hold the ownership of this // VideoDecoderFactory. - decoder_factory.reset(decoder_factory_tv_ = new RTCVideoDecoderFactoryTv()); + decoder_factory.reset(decoder_factory_tv_ = new RTCVideoDecoderFactoryTv); #endif - if (cmd_line->HasSwitch(switches::kEnableWebRtcHWEncoding)) - if (gpu_factories) - encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories)); - scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( webrtc::CreatePeerConnectionFactory(worker_thread_, signaling_thread_, audio_device_.get(), - encoder_factory.release(), + NULL, decoder_factory.release())); if (factory.get()) pc_factory_ = factory; diff --git a/chromium/content/renderer/media/media_stream_impl.cc b/chromium/content/renderer/media/media_stream_impl.cc index 6ce995e2608..5edc4cc5f16 100644 --- a/chromium/content/renderer/media/media_stream_impl.cc +++ b/chromium/content/renderer/media/media_stream_impl.cc @@ -75,11 +75,6 @@ void UpdateRequestOptions( options->video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; options->video_device_id = DesktopMediaID(DesktopMediaID::TYPE_SCREEN, 0).ToString(); - } else if (video_stream_source == kMediaStreamSourceDesktop) { - options->video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; - options->video_device_id = GetStreamConstraint( - user_media_request.videoConstraints(), - kMediaStreamSourceId, true); } } } diff --git a/chromium/content/renderer/media/peer_connection_tracker.cc b/chromium/content/renderer/media/peer_connection_tracker.cc index 597c6455704..44f44458aac 100644 --- a/chromium/content/renderer/media/peer_connection_tracker.cc +++ b/chromium/content/renderer/media/peer_connection_tracker.cc @@ -161,9 +161,15 @@ static base::DictionaryValue* GetDictValueStats( return NULL; DictionaryValue* dict = new base::DictionaryValue(); + if (!dict) + return NULL; dict->SetDouble("timestamp", report.timestamp); base::ListValue* values = new base::ListValue(); + if (!values) { + delete dict; + return NULL; + } dict->Set("values", values); for (size_t i = 0; i < report.values.size(); ++i) { @@ -183,10 +189,14 @@ static base::DictionaryValue* GetDictValue(const webrtc::StatsReport& report) { return NULL; result.reset(new base::DictionaryValue()); + if (!result) + return NULL; + // Note: // The format must be consistent with what webrtc_internals.js expects. // If you change it here, you must change webrtc_internals.js as well. - result->Set("stats", stats.release()); + if (stats) + result->Set("stats", stats.release()); result->SetString("id", report.id); result->SetString("type", report.type); diff --git a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.cc index f586497f484..d33e5901b2a 100644 --- a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.cc +++ b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.cc @@ -1,8 +1,8 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> @@ -17,8 +17,8 @@ namespace content { -RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} -RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( +RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {} +RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories( GpuChannelHost* gpu_channel_host, const scoped_refptr<base::MessageLoopProxy>& message_loop, WebGraphicsContext3DCommandBufferImpl* context) @@ -28,37 +28,32 @@ RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories( aborted_waiter_(true, false), message_loop_async_waiter_(false, false), render_thread_async_waiter_(false, false) { - // |context| is only required to support HW-accelerated decode. - if (!context) - return; - if (message_loop_->BelongsToCurrentThread()) { AsyncGetContext(context); message_loop_async_waiter_.Reset(); return; } // Wait for the context to be acquired. - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncGetContext, - // Unretained to avoid ref/deref'ing |*this|, which is not yet - // stored in a scoped_refptr. Safe because the Wait() below - // keeps us alive until this task completes. - base::Unretained(this), - // OK to pass raw because the pointee is only deleted on the - // compositor thread, and only as the result of a PostTask from - // the render thread which can only happen after this function - // returns, so our PostTask will run first. - context)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncGetContext, + // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a + // scoped_refptr. Safe because the Wait() below keeps us alive until this + // task completes. + base::Unretained(this), + // OK to pass raw because the pointee is only deleted on the compositor + // thread, and only as the result of a PostTask from the render thread + // which can only happen after this function returns, so our PostTask will + // run first. + context)); message_loop_async_waiter_.Wait(); } -RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories() +RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories() : aborted_waiter_(true, false), message_loop_async_waiter_(false, false), render_thread_async_waiter_(false, false) {} -void RendererGpuVideoAcceleratorFactories::AsyncGetContext( +void RendererGpuVideoDecoderFactories::AsyncGetContext( WebGraphicsContext3DCommandBufferImpl* context) { context_ = context->AsWeakPtr(); if (context_.get()) { @@ -71,23 +66,20 @@ void RendererGpuVideoAcceleratorFactories::AsyncGetContext( message_loop_async_waiter_.Signal(); } -scoped_ptr<media::VideoDecodeAccelerator> -RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( +media::VideoDecodeAccelerator* +RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator( media::VideoCodecProfile profile, media::VideoDecodeAccelerator::Client* client) { if (message_loop_->BelongsToCurrentThread()) { AsyncCreateVideoDecodeAccelerator(profile, client); message_loop_async_waiter_.Reset(); - return vda_.Pass(); + return vda_.release(); } // The VDA is returned in the vda_ member variable by the // AsyncCreateVideoDecodeAccelerator() function. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncCreateVideoDecodeAccelerator, - this, - profile, - client)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator, + this, profile, client)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; @@ -95,49 +87,17 @@ RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator( // If we are aborting and the VDA is created by the // AsyncCreateVideoDecodeAccelerator() function later we need to ensure // that it is destroyed on the same thread. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncDestroyVideoDecodeAccelerator, - this)); - return scoped_ptr<media::VideoDecodeAccelerator>(); - } - return vda_.Pass(); -} - -scoped_ptr<media::VideoEncodeAccelerator> -RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) { - if (message_loop_->BelongsToCurrentThread()) { - AsyncCreateVideoEncodeAccelerator(client); - message_loop_async_waiter_.Reset(); - return vea_.Pass(); - } - // The VEA is returned in the vea_ member variable by the - // AsyncCreateVideoEncodeAccelerator() function. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncCreateVideoEncodeAccelerator, - this, - client)); - - base::WaitableEvent* objects[] = {&aborted_waiter_, - &message_loop_async_waiter_}; - if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) { - // If we are aborting and the VDA is created by the - // AsyncCreateVideoEncodeAccelerator() function later we need to ensure - // that it is destroyed on the same thread. - message_loop_->PostTask(FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories:: - AsyncDestroyVideoEncodeAccelerator, - this)); - return scoped_ptr<media::VideoEncodeAccelerator>(); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator, + this)); + return NULL; } - return vea_.Pass(); + return vda_.release(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) { +void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) { DCHECK(message_loop_->BelongsToCurrentThread()); if (context_.get() && context_->GetCommandBufferProxy()) { @@ -147,17 +107,8 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) { - DCHECK(message_loop_->BelongsToCurrentThread()); - - vea_ = gpu_channel_host_->CreateVideoEncoder(client).Pass(); - message_loop_async_waiter_.Signal(); -} - -uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( - int32 count, - const gfx::Size& size, +uint32 RendererGpuVideoDecoderFactories::CreateTextures( + int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids, std::vector<gpu::Mailbox>* texture_mailboxes, uint32 texture_target) { @@ -170,14 +121,9 @@ uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( message_loop_async_waiter_.Reset(); return sync_point; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateTextures, - this, - count, - size, - texture_target, - &sync_point)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, + count, size, texture_target, &sync_point)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; @@ -188,10 +134,8 @@ uint32 RendererGpuVideoAcceleratorFactories::CreateTextures( return sync_point; } -void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( - int32 count, - const gfx::Size& size, - uint32 texture_target, +void RendererGpuVideoDecoderFactories::AsyncCreateTextures( + int32 count, const gfx::Size& size, uint32 texture_target, uint32* sync_point) { DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(texture_target); @@ -213,15 +157,8 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (texture_target == GL_TEXTURE_2D) { - gles2->TexImage2D(texture_target, - 0, - GL_RGBA, - size.width(), - size.height(), - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - NULL); + gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name); gles2->ProduceTextureCHROMIUM(texture_target, @@ -238,20 +175,16 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) { +void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { if (message_loop_->BelongsToCurrentThread()) { AsyncDeleteTexture(texture_id); return; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture, - this, - texture_id)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); } -void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture( - uint32 texture_id) { +void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_.get()) return; @@ -261,25 +194,23 @@ void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture( DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); } -void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) { +void RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) { if (message_loop_->BelongsToCurrentThread()) { AsyncWaitSyncPoint(sync_point); message_loop_async_waiter_.Reset(); return; } - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint, - this, - sync_point)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint, + this, + sync_point)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; base::WaitableEvent::WaitMany(objects, arraysize(objects)); } -void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint( - uint32 sync_point) { +void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_) { message_loop_async_waiter_.Signal(); @@ -291,10 +222,9 @@ void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint( message_loop_async_waiter_.Signal(); } -void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, - uint32 texture_target, - const gfx::Size& size, - const SkBitmap& pixels) { +void RendererGpuVideoDecoderFactories::ReadPixels( + uint32 texture_id, uint32 texture_target, const gfx::Size& size, + const SkBitmap& pixels) { // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. // Multiple SkBitmaps can share a SkPixelRef instance. We use this to // ensure that the underlying pixels in the SkBitmap passed in remain valid @@ -302,13 +232,9 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); if (!message_loop_->BelongsToCurrentThread()) { - message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels, - this, - texture_id, - texture_target, - size)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncReadPixels, this, + texture_id, texture_target, size)); base::WaitableEvent* objects[] = {&aborted_waiter_, &message_loop_async_waiter_}; if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) @@ -320,10 +246,8 @@ void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id, read_pixels_bitmap_.setPixelRef(NULL); } -void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( - uint32 texture_id, - uint32 texture_target, - const gfx::Size& size) { +void RendererGpuVideoDecoderFactories::AsyncReadPixels( + uint32 texture_id, uint32 texture_target, const gfx::Size& size) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!context_.get()) { message_loop_async_waiter_.Signal(); @@ -345,32 +269,25 @@ void RendererGpuVideoAcceleratorFactories::AsyncReadPixels( GLuint fb; gles2->GenFramebuffers(1, &fb); gles2->BindFramebuffer(GL_FRAMEBUFFER, fb); - gles2->FramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, tmp_texture, 0); + gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + texture_target, tmp_texture, 0); gles2->PixelStorei(GL_PACK_ALIGNMENT, 4); - gles2->ReadPixels(0, - 0, - size.width(), - size.height(), - GL_BGRA_EXT, - GL_UNSIGNED_BYTE, - read_pixels_bitmap_.pixelRef()->pixels()); + gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT, + GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels()); gles2->DeleteFramebuffers(1, &fb); gles2->DeleteTextures(1, &tmp_texture); DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); message_loop_async_waiter_.Signal(); } -base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( +base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( size_t size) { if (main_message_loop_->BelongsToCurrentThread()) { return ChildThread::current()->AllocateSharedMemory(size); } - main_message_loop_->PostTask( - FROM_HERE, - base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory, - this, - size)); + main_message_loop_->PostTask(FROM_HERE, base::Bind( + &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, + size)); base::WaitableEvent* objects[] = {&aborted_waiter_, &render_thread_async_waiter_}; @@ -379,8 +296,7 @@ base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory( return shared_memory_segment_.release(); } -void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory( - size_t size) { +void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) { DCHECK_EQ(base::MessageLoop::current(), ChildThread::current()->message_loop()); @@ -390,20 +306,22 @@ void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory( } scoped_refptr<base::MessageLoopProxy> -RendererGpuVideoAcceleratorFactories::GetMessageLoop() { +RendererGpuVideoDecoderFactories::GetMessageLoop() { return message_loop_; } -void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); } +void RendererGpuVideoDecoderFactories::Abort() { + aborted_waiter_.Signal(); +} -bool RendererGpuVideoAcceleratorFactories::IsAborted() { +bool RendererGpuVideoDecoderFactories::IsAborted() { return aborted_waiter_.IsSignaled(); } -scoped_refptr<RendererGpuVideoAcceleratorFactories> -RendererGpuVideoAcceleratorFactories::Clone() { - scoped_refptr<RendererGpuVideoAcceleratorFactories> factories = - new RendererGpuVideoAcceleratorFactories(); +scoped_refptr<media::GpuVideoDecoderFactories> +RendererGpuVideoDecoderFactories::Clone() { + scoped_refptr<RendererGpuVideoDecoderFactories> factories = + new RendererGpuVideoDecoderFactories(); factories->message_loop_ = message_loop_; factories->main_message_loop_ = main_message_loop_; factories->gpu_channel_host_ = gpu_channel_host_; @@ -411,18 +329,10 @@ RendererGpuVideoAcceleratorFactories::Clone() { return factories; } -void -RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() { +void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { // OK to release because Destroy() will delete the VDA instance. if (vda_) vda_.release()->Destroy(); } -void -RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoEncodeAccelerator() { - // OK to release because Destroy() will delete the VDA instance. - if (vea_) - vea_.release()->Destroy(); -} - } // namespace content diff --git a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.h b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.h index fcc4ffb411a..32f9bcdf227 100644 --- a/chromium/content/renderer/media/renderer_gpu_video_accelerator_factories.h +++ b/chromium/content/renderer/media/renderer_gpu_video_decoder_factories.h @@ -1,9 +1,9 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. -#ifndef CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ -#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ +#ifndef CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ +#define CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ #include <vector> @@ -12,7 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/waitable_event.h" #include "content/common/content_export.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/size.h" @@ -25,7 +25,7 @@ namespace content { class GpuChannelHost; class WebGraphicsContext3DCommandBufferImpl; -// Glue code to expose functionality needed by media::GpuVideoAccelerator to +// Glue code to expose functionality needed by media::GpuVideoDecoder to // RenderViewImpl. This class is entirely an implementation detail of // RenderViewImpl and only has its own header to allow extraction of its // implementation from render_view_impl.cc which is already far too large. @@ -34,31 +34,27 @@ class WebGraphicsContext3DCommandBufferImpl; // internally trampolined to the appropriate thread. GPU/GL-related calls go to // the constructor-argument loop (the media thread), and shmem-related calls go // to the render thread. -class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories - : public media::GpuVideoAcceleratorFactories { +class CONTENT_EXPORT RendererGpuVideoDecoderFactories + : public media::GpuVideoDecoderFactories { public: // Takes a ref on |gpu_channel_host| and tests |context| for loss before each // use. - RendererGpuVideoAcceleratorFactories( + RendererGpuVideoDecoderFactories( GpuChannelHost* gpu_channel_host, const scoped_refptr<base::MessageLoopProxy>& message_loop, WebGraphicsContext3DCommandBufferImpl* wgc3dcbi); - // media::GpuVideoAcceleratorFactories implementation. - virtual scoped_ptr<media::VideoDecodeAccelerator> - CreateVideoDecodeAccelerator( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) OVERRIDE; - virtual scoped_ptr<media::VideoEncodeAccelerator> - CreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client) OVERRIDE; + // media::GpuVideoDecoderFactories implementation. + virtual media::VideoDecodeAccelerator* CreateVideoDecodeAccelerator( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) OVERRIDE; // Creates textures and produces them into mailboxes. Returns a sync point to // wait on before using the mailboxes, or 0 on failure. - virtual uint32 CreateTextures(int32 count, - const gfx::Size& size, - std::vector<uint32>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32 texture_target) OVERRIDE; + virtual uint32 CreateTextures( + int32 count, const gfx::Size& size, + std::vector<uint32>* texture_ids, + std::vector<gpu::Mailbox>* texture_mailboxes, + uint32 texture_target) OVERRIDE; virtual void DeleteTexture(uint32 texture_id) OVERRIDE; virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE; virtual void ReadPixels(uint32 texture_id, @@ -69,14 +65,16 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE; virtual void Abort() OVERRIDE; virtual bool IsAborted() OVERRIDE; - scoped_refptr<RendererGpuVideoAcceleratorFactories> Clone(); + + // Makes a copy of |this|. + scoped_refptr<media::GpuVideoDecoderFactories> Clone(); protected: - friend class base::RefCountedThreadSafe<RendererGpuVideoAcceleratorFactories>; - virtual ~RendererGpuVideoAcceleratorFactories(); + friend class base::RefCountedThreadSafe<RendererGpuVideoDecoderFactories>; + virtual ~RendererGpuVideoDecoderFactories(); private: - RendererGpuVideoAcceleratorFactories(); + RendererGpuVideoDecoderFactories(); // Helper for the constructor to acquire the ContentGLContext on // |message_loop_|. @@ -87,25 +85,19 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories // (except for DeleteTexture, which is fire-and-forget). // AsyncCreateSharedMemory runs on the renderer thread and the rest run on // |message_loop_|. - // AsyncCreateVideoDecodeAccelerator returns its output in the |vda_| member. - // AsyncCreateVideoEncodeAccelerator returns its output in the |vea_| member. + // The AsyncCreateVideoDecodeAccelerator returns its output in the vda_ + // member. void AsyncCreateVideoDecodeAccelerator( media::VideoCodecProfile profile, media::VideoDecodeAccelerator::Client* client); - void AsyncCreateVideoEncodeAccelerator( - media::VideoEncodeAccelerator::Client* client); - void AsyncCreateTextures(int32 count, - const gfx::Size& size, - uint32 texture_target, - uint32* sync_point); + void AsyncCreateTextures(int32 count, const gfx::Size& size, + uint32 texture_target, uint32* sync_point); void AsyncDeleteTexture(uint32 texture_id); void AsyncWaitSyncPoint(uint32 sync_point); - void AsyncReadPixels(uint32 texture_id, - uint32 texture_target, + void AsyncReadPixels(uint32 texture_id, uint32 texture_target, const gfx::Size& size); void AsyncCreateSharedMemory(size_t size); void AsyncDestroyVideoDecodeAccelerator(); - void AsyncDestroyVideoEncodeAccelerator(); scoped_refptr<base::MessageLoopProxy> message_loop_; scoped_refptr<base::MessageLoopProxy> main_message_loop_; @@ -124,12 +116,9 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories // message loop to indicate their completion. e.g. AsyncCreateSharedMemory. base::WaitableEvent render_thread_async_waiter_; - // The vda returned by the CreateVideoDecodeAccelerator function. + // The vda returned by the CreateVideoAcclelerator function. scoped_ptr<media::VideoDecodeAccelerator> vda_; - // The vea returned by the CreateVideoEncodeAccelerator function. - scoped_ptr<media::VideoEncodeAccelerator> vea_; - // Shared memory segment which is returned by the CreateSharedMemory() // function. scoped_ptr<base::SharedMemory> shared_memory_segment_; @@ -141,9 +130,9 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories std::vector<uint32> created_textures_; std::vector<gpu::Mailbox> created_texture_mailboxes_; - DISALLOW_COPY_AND_ASSIGN(RendererGpuVideoAcceleratorFactories); + DISALLOW_COPY_AND_ASSIGN(RendererGpuVideoDecoderFactories); }; } // namespace content -#endif // CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_ +#endif // CONTENT_RENDERER_MEDIA_RENDERER_GPU_VIDEO_DECODER_FACTORIES_H_ diff --git a/chromium/content/renderer/media/rtc_video_decoder.cc b/chromium/content/renderer/media/rtc_video_decoder.cc index 27030f69514..12904f11850 100644 --- a/chromium/content/renderer/media/rtc_video_decoder.cc +++ b/chromium/content/renderer/media/rtc_video_decoder.cc @@ -13,7 +13,7 @@ #include "base/task_runner_util.h" #include "content/child/child_thread.h" #include "media/base/bind_to_loop.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "third_party/webrtc/system_wrappers/interface/ref_count.h" namespace content { @@ -69,7 +69,7 @@ RTCVideoDecoder::BufferData::BufferData() {} RTCVideoDecoder::BufferData::~BufferData() {} RTCVideoDecoder::RTCVideoDecoder( - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories) + const scoped_refptr<media::GpuVideoDecoderFactories>& factories) : weak_factory_(this), weak_this_(weak_factory_.GetWeakPtr()), factories_(factories), @@ -122,7 +122,7 @@ RTCVideoDecoder::~RTCVideoDecoder() { scoped_ptr<RTCVideoDecoder> RTCVideoDecoder::Create( webrtc::VideoCodecType type, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories) { + const scoped_refptr<media::GpuVideoDecoderFactories>& factories) { scoped_ptr<RTCVideoDecoder> decoder; // Convert WebRTC codec type to media codec profile. media::VideoCodecProfile profile; @@ -136,8 +136,8 @@ scoped_ptr<RTCVideoDecoder> RTCVideoDecoder::Create( } decoder.reset(new RTCVideoDecoder(factories)); - decoder->vda_ = - factories->CreateVideoDecodeAccelerator(profile, decoder.get()).Pass(); + decoder->vda_ + .reset(factories->CreateVideoDecodeAccelerator(profile, decoder.get())); // vda can be NULL if VP8 is not supported. if (decoder->vda_ != NULL) { decoder->state_ = INITIALIZED; @@ -397,7 +397,7 @@ scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( visible_rect, natural_size, timestamp_ms, - base::Bind(&media::GpuVideoAcceleratorFactories::ReadPixels, + base::Bind(&media::GpuVideoDecoderFactories::ReadPixels, factories_, pb.texture_id(), decoder_texture_target_, diff --git a/chromium/content/renderer/media/rtc_video_decoder.h b/chromium/content/renderer/media/rtc_video_decoder.h index 7a2686e672a..11e58527145 100644 --- a/chromium/content/renderer/media/rtc_video_decoder.h +++ b/chromium/content/renderer/media/rtc_video_decoder.h @@ -30,7 +30,7 @@ class MessageLoopProxy; namespace media { class DecoderBuffer; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; } namespace content { @@ -52,7 +52,7 @@ class CONTENT_EXPORT RTCVideoDecoder // run on the message loop of |factories|. static scoped_ptr<RTCVideoDecoder> Create( webrtc::VideoCodecType type, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories); + const scoped_refptr<media::GpuVideoDecoderFactories>& factories); // webrtc::VideoDecoder implementation. // Called on WebRTC DecodingThread. @@ -113,7 +113,7 @@ class CONTENT_EXPORT RTCVideoDecoder // The meessage loop of |factories| will be saved to |vda_loop_proxy_|. RTCVideoDecoder( - const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories); + const scoped_refptr<media::GpuVideoDecoderFactories>& factories); void Initialize(base::WaitableEvent* waiter); @@ -197,7 +197,7 @@ class CONTENT_EXPORT RTCVideoDecoder base::WeakPtrFactory<RTCVideoDecoder> weak_factory_; base::WeakPtr<RTCVideoDecoder> weak_this_; - scoped_refptr<media::GpuVideoAcceleratorFactories> factories_; + scoped_refptr<media::GpuVideoDecoderFactories> factories_; // The message loop to run callbacks on. This is from |factories_|. scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.cc b/chromium/content/renderer/media/rtc_video_decoder_factory.cc index 57b6a580c3a..e621735dbcc 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_factory.cc +++ b/chromium/content/renderer/media/rtc_video_decoder_factory.cc @@ -6,13 +6,14 @@ #include "base/location.h" #include "base/memory/scoped_ptr.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "content/renderer/media/rtc_video_decoder.h" +#include "media/filters/gpu_video_decoder_factories.h" namespace content { RTCVideoDecoderFactory::RTCVideoDecoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) + const scoped_refptr<RendererGpuVideoDecoderFactories>& gpu_factories) : gpu_factories_(gpu_factories) { DVLOG(2) << "RTCVideoDecoderFactory"; } @@ -24,7 +25,7 @@ RTCVideoDecoderFactory::~RTCVideoDecoderFactory() { webrtc::VideoDecoder* RTCVideoDecoderFactory::CreateVideoDecoder( webrtc::VideoCodecType type) { DVLOG(2) << "CreateVideoDecoder"; - // GpuVideoAcceleratorFactories is not thread safe. It cannot be shared + // RendererGpuVideoDecoderFactories is not thread safe. It cannot be shared // by different decoders. This method runs on Chrome_libJingle_WorkerThread // and the child thread is blocked while this runs. We cannot create new gpu // factories here. Clone one instead. diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.h b/chromium/content/renderer/media/rtc_video_decoder_factory.h index f7a42a3cd47..1455d7b61ee 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_factory.h +++ b/chromium/content/renderer/media/rtc_video_decoder_factory.h @@ -11,19 +11,23 @@ #include "third_party/libjingle/source/talk/media/webrtc/webrtcvideodecoderfactory.h" #include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +namespace media { +class GpuVideoDecoderFactories; +} + namespace webrtc { class VideoDecoder; } namespace content { -class RendererGpuVideoAcceleratorFactories; +class RendererGpuVideoDecoderFactories; // TODO(wuchengli): add unittest. class CONTENT_EXPORT RTCVideoDecoderFactory : NON_EXPORTED_BASE(public cricket::WebRtcVideoDecoderFactory) { public: explicit RTCVideoDecoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); + const scoped_refptr<RendererGpuVideoDecoderFactories>& gpu_factories); virtual ~RTCVideoDecoderFactory(); // Runs on Chrome_libJingle_WorkerThread. The child thread is blocked while @@ -36,7 +40,7 @@ class CONTENT_EXPORT RTCVideoDecoderFactory virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) OVERRIDE; private: - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories_; DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoderFactory); }; diff --git a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc b/chromium/content/renderer/media/rtc_video_decoder_unittest.cc index 3355b6a3386..2ffeb3e4b61 100644 --- a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc +++ b/chromium/content/renderer/media/rtc_video_decoder_unittest.cc @@ -8,7 +8,7 @@ #include "base/threading/thread.h" #include "content/renderer/media/rtc_video_decoder.h" #include "media/base/gmock_callback_support.h" -#include "media/filters/mock_gpu_video_accelerator_factories.h" +#include "media/filters/mock_gpu_video_decoder_factories.h" #include "media/video/mock_video_decode_accelerator.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +25,7 @@ class RTCVideoDecoderTest : public ::testing::Test, webrtc::DecodedImageCallback { public: RTCVideoDecoderTest() - : mock_gpu_factories_(new media::MockGpuVideoAcceleratorFactories), + : mock_gpu_factories_(new media::MockGpuVideoDecoderFactories), vda_thread_("vda_thread"), idle_waiter_(false, false) { memset(&codec_, 0, sizeof(codec_)); @@ -37,11 +37,11 @@ class RTCVideoDecoderTest : public ::testing::Test, mock_vda_ = new media::MockVideoDecodeAccelerator; EXPECT_CALL(*mock_gpu_factories_, GetMessageLoop()) .WillRepeatedly(Return(vda_loop_proxy_)); - EXPECT_CALL(*mock_gpu_factories_, DoCreateVideoDecodeAccelerator(_, _)) + EXPECT_CALL(*mock_gpu_factories_, CreateVideoDecodeAccelerator(_, _)) .WillRepeatedly( Return(static_cast<media::VideoDecodeAccelerator*>(NULL))); EXPECT_CALL(*mock_gpu_factories_, - DoCreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) + CreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) .WillRepeatedly(Return(mock_vda_)); EXPECT_CALL(*mock_gpu_factories_, Abort()).WillRepeatedly(Return()); EXPECT_CALL(*mock_gpu_factories_, CreateSharedMemory(_)) @@ -94,7 +94,7 @@ class RTCVideoDecoderTest : public ::testing::Test, } protected: - scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; + scoped_refptr<media::MockGpuVideoDecoderFactories> mock_gpu_factories_; media::MockVideoDecodeAccelerator* mock_vda_; scoped_ptr<RTCVideoDecoder> rtc_decoder_; webrtc::VideoCodec codec_; diff --git a/chromium/content/renderer/media/rtc_video_encoder.cc b/chromium/content/renderer/media/rtc_video_encoder.cc deleted file mode 100644 index 416317d3635..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder.cc +++ /dev/null @@ -1,658 +0,0 @@ -// Copyright 2013 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/renderer/media/rtc_video_encoder.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/scoped_vector.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/synchronization/waitable_event.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" -#include "media/base/bitstream_buffer.h" -#include "media/base/video_frame.h" -#include "media/filters/gpu_video_accelerator_factories.h" -#include "media/video/video_encode_accelerator.h" - -#define NOTIFY_ERROR(x) \ - do { \ - DLOG(ERROR) << "calling NotifyError(): " << x; \ - NotifyError(x); \ - } while (0) - -namespace content { - -// This private class of RTCVideoEncoder does the actual work of communicating -// with a media::VideoEncodeAccelerator for handling video encoding. It can -// be created on any thread, but should subsequently be posted to (and Destroy() -// called on) a single thread. Callbacks to RTCVideoEncoder are posted to the -// thread on which the instance was constructed. -// -// This class separates state related to the thread that RTCVideoEncoder -// operates on (presently the libjingle worker thread) from the thread that -// |gpu_factories_| provides for accelerator operations (presently the media -// thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while -// RTCVideoEncoder::Impl stays around long enough to properly shut down the VEA. -class RTCVideoEncoder::Impl - : public media::VideoEncodeAccelerator::Client, - public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> { - public: - Impl( - const base::WeakPtr<RTCVideoEncoder>& weak_encoder, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - - // Create the VEA and call Initialize() on it. Called once per instantiation, - // and then the instance is bound forevermore to whichever thread made the - // call. - // RTCVideoEncoder expects to be able to call this function synchronously from - // its own thread, hence the |async_waiter| and |async_retval| arguments. - void CreateAndInitializeVEA(const gfx::Size& input_visible_size, - uint32 bitrate, - media::VideoCodecProfile profile, - base::WaitableEvent* async_waiter, - int32_t* async_retval); - // Enqueue a frame from WebRTC for encoding. - // RTCVideoEncoder expects to be able to call this function synchronously from - // its own thread, hence the |async_waiter| and |async_retval| arguments. - void Enqueue(const webrtc::I420VideoFrame* input_frame, - bool force_keyframe, - base::WaitableEvent* async_waiter, - int32_t* async_retval); - - // RTCVideoEncoder is given a buffer to be passed to WebRTC through the - // RTCVideoEncoder::ReturnEncodedImage() function. When that is complete, - // the buffer is returned to Impl by its index using this function. - void UseOutputBitstreamBufferId(int32 bitstream_buffer_id); - - // Request encoding parameter change for the underlying encoder. - void RequestEncodingParametersChange(uint32 bitrate, uint32 framerate); - - // Destroy this Impl's encoder. The destructor is not explicitly called, as - // Impl is a base::RefCountedThreadSafe. - void Destroy(); - - // media::VideoEncodeAccelerator::Client implementation. - virtual void NotifyInitializeDone() OVERRIDE; - virtual void RequireBitstreamBuffers(unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) OVERRIDE; - virtual void BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) OVERRIDE; - virtual void NotifyError(media::VideoEncodeAccelerator::Error error) OVERRIDE; - - private: - friend class base::RefCountedThreadSafe<Impl>; - - enum { - kInputBufferExtraCount = 1, // The number of input buffers allocated, more - // than what is requested by - // VEA::RequireBitstreamBuffers(). - kOutputBufferCount = 3, - }; - - virtual ~Impl(); - - // Perform encoding on an input frame from the input queue. - void EncodeOneFrame(); - - // Notify that an input frame is finished for encoding. |index| is the index - // of the completed frame in |input_buffers_|. - void EncodeFrameFinished(int index); - - // Set up/signal |async_waiter_| and |async_retval_|; see declarations below. - void RegisterAsyncWaiter(base::WaitableEvent* waiter, int32_t* retval); - void SignalAsyncWaiter(int32_t retval); - - base::ThreadChecker thread_checker_; - - // Weak pointer to the parent RTCVideoEncoder, for posting back VEA::Client - // notifications. - const base::WeakPtr<RTCVideoEncoder> weak_encoder_; - - // The message loop on which to post callbacks to |weak_encoder_|. - const scoped_refptr<base::MessageLoopProxy> encoder_message_loop_proxy_; - - // Factory for creating VEAs, shared memory buffers, etc. - const scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // webrtc::VideoEncoder expects InitEncode() and Encode() to be synchronous. - // Do this by waiting on the |async_waiter_| and returning the return value in - // |async_retval_| when initialization completes, encoding completes, or - // an error occurs. - base::WaitableEvent* async_waiter_; - int32_t* async_retval_; - - // The underlying VEA to perform encoding on. - scoped_ptr<media::VideoEncodeAccelerator> video_encoder_; - - // Next input frame. Since there is at most one next frame, a single-element - // queue is sufficient. - const webrtc::I420VideoFrame* input_next_frame_; - - // Whether to encode a keyframe next. - bool input_next_frame_keyframe_; - - // Frame sizes. - gfx::Size input_frame_coded_size_; - gfx::Size input_visible_size_; - - // Shared memory buffers for input/output with the VEA. - ScopedVector<base::SharedMemory> input_buffers_; - ScopedVector<base::SharedMemory> output_buffers_; - - // Input buffers ready to be filled with input from Encode(). As a LIFO since - // we don't care about ordering. - std::vector<int> input_buffers_free_; - - // Timestamp of first frame returned from encoder. We calculate subsequent - // capture times as deltas from this base. - base::Time time_base_; - - DISALLOW_COPY_AND_ASSIGN(Impl); -}; - -RTCVideoEncoder::Impl::Impl( - const base::WeakPtr<RTCVideoEncoder>& weak_encoder, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : weak_encoder_(weak_encoder), - encoder_message_loop_proxy_(base::MessageLoopProxy::current()), - gpu_factories_(gpu_factories), - async_waiter_(NULL), - async_retval_(NULL), - input_next_frame_(NULL), - input_next_frame_keyframe_(false) { - thread_checker_.DetachFromThread(); -} - -void RTCVideoEncoder::Impl::CreateAndInitializeVEA( - const gfx::Size& input_visible_size, - uint32 bitrate, - media::VideoCodecProfile profile, - base::WaitableEvent* async_waiter, - int32_t* async_retval) { - DVLOG(3) << "Impl::CreateAndInitializeVEA()"; - DCHECK(thread_checker_.CalledOnValidThread()); - - RegisterAsyncWaiter(async_waiter, async_retval); - - // Check for overflow converting bitrate (kilobits/sec) to bits/sec. - if (bitrate > kuint32max / 1000) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); - return; - } - - video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(this).Pass(); - if (!video_encoder_) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - input_visible_size_ = input_visible_size; - video_encoder_->Initialize( - media::VideoFrame::I420, input_visible_size_, profile, bitrate * 1000); -} - -void RTCVideoEncoder::Impl::Enqueue(const webrtc::I420VideoFrame* input_frame, - bool force_keyframe, - base::WaitableEvent* async_waiter, - int32_t* async_retval) { - DVLOG(3) << "Impl::Enqueue()"; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!input_next_frame_); - - RegisterAsyncWaiter(async_waiter, async_retval); - input_next_frame_ = input_frame; - input_next_frame_keyframe_ = force_keyframe; - - if (!input_buffers_free_.empty()) - EncodeOneFrame(); -} - -void RTCVideoEncoder::Impl::UseOutputBitstreamBufferId( - int32 bitstream_buffer_id) { - DVLOG(3) << "Impl::UseOutputBitstreamBufferIndex(): " - "bitstream_buffer_id=" << bitstream_buffer_id; - DCHECK(thread_checker_.CalledOnValidThread()); - if (video_encoder_) { - video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( - bitstream_buffer_id, - output_buffers_[bitstream_buffer_id]->handle(), - output_buffers_[bitstream_buffer_id]->mapped_size())); - } -} - -void RTCVideoEncoder::Impl::RequestEncodingParametersChange(uint32 bitrate, - uint32 framerate) { - DVLOG(3) << "Impl::RequestEncodingParametersChange(): bitrate=" << bitrate - << ", framerate=" << framerate; - DCHECK(thread_checker_.CalledOnValidThread()); - - // Check for overflow converting bitrate (kilobits/sec) to bits/sec. - if (bitrate > kuint32max / 1000) { - NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); - return; - } - - if (video_encoder_) - video_encoder_->RequestEncodingParametersChange(bitrate * 1000, framerate); -} - -void RTCVideoEncoder::Impl::Destroy() { - DVLOG(3) << "Impl::Destroy()"; - DCHECK(thread_checker_.CalledOnValidThread()); - if (video_encoder_) - video_encoder_.release()->Destroy(); -} - -void RTCVideoEncoder::Impl::NotifyInitializeDone() { - DVLOG(3) << "Impl::NotifyInitializeDone()"; - DCHECK(thread_checker_.CalledOnValidThread()); - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); -} - -void RTCVideoEncoder::Impl::RequireBitstreamBuffers( - unsigned int input_count, - const gfx::Size& input_coded_size, - size_t output_buffer_size) { - DVLOG(3) << "Impl::RequireBitstreamBuffers(): input_count=" << input_count - << ", input_coded_size=" << input_coded_size.ToString() - << ", output_buffer_size=" << output_buffer_size; - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!video_encoder_) - return; - - input_frame_coded_size_ = input_coded_size; - - for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) { - base::SharedMemory* shm = - gpu_factories_->CreateSharedMemory(input_coded_size.GetArea() * 3 / 2); - if (!shm) { - DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): " - "failed to create input buffer " << i; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - input_buffers_.push_back(shm); - input_buffers_free_.push_back(i); - } - - for (int i = 0; i < kOutputBufferCount; ++i) { - base::SharedMemory* shm = - gpu_factories_->CreateSharedMemory(output_buffer_size); - if (!shm) { - DLOG(ERROR) << "Impl::RequireBitstreamBuffers(): " - "failed to create output buffer " << i; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - output_buffers_.push_back(shm); - } - - // Immediately provide all output buffers to the VEA. - for (size_t i = 0; i < output_buffers_.size(); ++i) { - video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( - i, output_buffers_[i]->handle(), output_buffers_[i]->mapped_size())); - } -} - -void RTCVideoEncoder::Impl::BitstreamBufferReady(int32 bitstream_buffer_id, - size_t payload_size, - bool key_frame) { - DVLOG(3) << "Impl::BitstreamBufferReady(): " - "bitstream_buffer_id=" << bitstream_buffer_id - << ", payload_size=" << payload_size - << ", key_frame=" << key_frame; - DCHECK(thread_checker_.CalledOnValidThread()); - - if (bitstream_buffer_id < 0 || - bitstream_buffer_id >= static_cast<int>(output_buffers_.size())) { - DLOG(ERROR) << "Impl::BitstreamBufferReady(): invalid bitstream_buffer_id=" - << bitstream_buffer_id; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; - if (payload_size > output_buffer->mapped_size()) { - DLOG(ERROR) << "Impl::BitstreamBufferReady(): invalid payload_size=" - << payload_size; - NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); - return; - } - - const base::Time now = base::Time::Now(); - if (time_base_.is_null()) - time_base_ = now; - const base::TimeDelta delta = now - time_base_; - - scoped_ptr<webrtc::EncodedImage> image(new webrtc::EncodedImage( - reinterpret_cast<uint8_t*>(output_buffer->memory()), - payload_size, - output_buffer->mapped_size())); - image->_encodedWidth = input_visible_size_.width(); - image->_encodedHeight = input_visible_size_.height(); - // Convert capture time to 90 kHz RTP timestamp. - image->_timeStamp = (delta * 90000).InSeconds(); - image->capture_time_ms_ = delta.InMilliseconds(); - image->_frameType = (key_frame ? webrtc::kKeyFrame : webrtc::kDeltaFrame); - image->_completeFrame = true; - - encoder_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::ReturnEncodedImage, - weak_encoder_, - base::Passed(&image), - bitstream_buffer_id)); -} - -void RTCVideoEncoder::Impl::NotifyError( - media::VideoEncodeAccelerator::Error error) { - DVLOG(3) << "Impl::NotifyError(): error=" << error; - DCHECK(thread_checker_.CalledOnValidThread()); - int32_t retval; - switch (error) { - case media::VideoEncodeAccelerator::kInvalidArgumentError: - retval = WEBRTC_VIDEO_CODEC_ERR_PARAMETER; - break; - default: - retval = WEBRTC_VIDEO_CODEC_ERROR; - } - - if (video_encoder_) - video_encoder_.release()->Destroy(); - - if (async_waiter_) { - SignalAsyncWaiter(retval); - } else { - encoder_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::NotifyError, weak_encoder_, retval)); - } -} - -RTCVideoEncoder::Impl::~Impl() { DCHECK(!video_encoder_); } - -void RTCVideoEncoder::Impl::EncodeOneFrame() { - DVLOG(3) << "Impl::EncodeOneFrame()"; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(input_next_frame_); - DCHECK(!input_buffers_free_.empty()); - - // EncodeOneFrame() may re-enter EncodeFrameFinished() if VEA::Encode() fails, - // we receive a VEA::NotifyError(), and the media::VideoFrame we pass to - // Encode() gets destroyed early. Handle this by resetting our - // input_next_frame_* state before we hand off the VideoFrame to the VEA. - const webrtc::I420VideoFrame* next_frame = input_next_frame_; - bool next_frame_keyframe = input_next_frame_keyframe_; - input_next_frame_ = NULL; - input_next_frame_keyframe_ = false; - - if (!video_encoder_) { - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_ERROR); - return; - } - - const int index = input_buffers_free_.back(); - base::SharedMemory* input_buffer = input_buffers_[index]; - - // Do a strided copy of the input frame to match the input requirements for - // the encoder. - // TODO(sheu): support zero-copy from WebRTC. http://crbug.com/269312 - const uint8_t* src = next_frame->buffer(webrtc::kYPlane); - uint8* dst = reinterpret_cast<uint8*>(input_buffer->memory()); - uint8* const y_dst = dst; - int width = input_frame_coded_size_.width(); - int stride = next_frame->stride(webrtc::kYPlane); - for (int i = 0; i < next_frame->height(); ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - src = next_frame->buffer(webrtc::kUPlane); - width = input_frame_coded_size_.width() / 2; - stride = next_frame->stride(webrtc::kUPlane); - for (int i = 0; i < next_frame->height() / 2; ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - src = next_frame->buffer(webrtc::kVPlane); - width = input_frame_coded_size_.width() / 2; - stride = next_frame->stride(webrtc::kVPlane); - for (int i = 0; i < next_frame->height() / 2; ++i) { - memcpy(dst, src, width); - src += stride; - dst += width; - } - - scoped_refptr<media::VideoFrame> frame = - media::VideoFrame::WrapExternalSharedMemory( - media::VideoFrame::I420, - input_frame_coded_size_, - gfx::Rect(input_visible_size_), - input_visible_size_, - y_dst, - input_buffer->handle(), - base::TimeDelta(), - base::Bind(&RTCVideoEncoder::Impl::EncodeFrameFinished, this, index)); - - video_encoder_->Encode(frame, next_frame_keyframe); - input_buffers_free_.pop_back(); - SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK); -} - -void RTCVideoEncoder::Impl::EncodeFrameFinished(int index) { - DVLOG(3) << "Impl::EncodeFrameFinished(): index=" << index; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_GE(index, 0); - DCHECK_LT(index, static_cast<int>(input_buffers_.size())); - input_buffers_free_.push_back(index); - if (input_next_frame_) - EncodeOneFrame(); -} - -void RTCVideoEncoder::Impl::RegisterAsyncWaiter(base::WaitableEvent* waiter, - int32_t* retval) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!async_waiter_); - DCHECK(!async_retval_); - async_waiter_ = waiter; - async_retval_ = retval; -} - -void RTCVideoEncoder::Impl::SignalAsyncWaiter(int32_t retval) { - DCHECK(thread_checker_.CalledOnValidThread()); - *async_retval_ = retval; - async_waiter_->Signal(); - async_retval_ = NULL; - async_waiter_ = NULL; -} - -#undef NOTIFY_ERROR - -//////////////////////////////////////////////////////////////////////////////// -// -// RTCVideoEncoder -// -//////////////////////////////////////////////////////////////////////////////// - -RTCVideoEncoder::RTCVideoEncoder( - webrtc::VideoCodecType type, - media::VideoCodecProfile profile, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : video_codec_type_(type), - video_codec_profile_(profile), - gpu_factories_(gpu_factories), - encoded_image_callback_(NULL), - impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) { - DVLOG(1) << "RTCVideoEncoder(): profile=" << profile; -} - -RTCVideoEncoder::~RTCVideoEncoder() { - DCHECK(thread_checker_.CalledOnValidThread()); - Release(); - DCHECK(!impl_); -} - -int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, - int32_t number_of_cores, - uint32_t max_payload_size) { - DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType - << ", width=" << codec_settings->width - << ", height=" << codec_settings->height - << ", startBitrate=" << codec_settings->startBitrate; - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!impl_); - - weak_this_factory_.reset(new base::WeakPtrFactory<RTCVideoEncoder>(this)); - impl_ = new Impl(weak_this_factory_->GetWeakPtr(), gpu_factories_); - base::WaitableEvent initialization_waiter(true, false); - int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, - impl_, - gfx::Size(codec_settings->width, codec_settings->height), - codec_settings->startBitrate, - video_codec_profile_, - &initialization_waiter, - &initialization_retval)); - - // webrtc::VideoEncoder expects this call to be synchronous. - initialization_waiter.Wait(); - return initialization_retval; -} - -int32_t RTCVideoEncoder::Encode( - const webrtc::I420VideoFrame& input_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const std::vector<webrtc::VideoFrameType>* frame_types) { - DVLOG(3) << "Encode()"; - // TODO(sheu): figure out why this check fails. - // DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "Encode(): returning impl_status_=" << impl_status_; - return impl_status_; - } - - base::WaitableEvent encode_waiter(true, false); - int32_t encode_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::Enqueue, - impl_, - &input_image, - (frame_types->front() == webrtc::kKeyFrame), - &encode_waiter, - &encode_retval)); - - // webrtc::VideoEncoder expects this call to be synchronous. - encode_waiter.Wait(); - DVLOG(3) << "Encode(): returning encode_retval=" << encode_retval; - return encode_retval; -} - -int32_t RTCVideoEncoder::RegisterEncodeCompleteCallback( - webrtc::EncodedImageCallback* callback) { - DVLOG(3) << "RegisterEncodeCompleteCallback()"; - DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "RegisterEncodeCompleteCallback(): returning " << impl_status_; - return impl_status_; - } - - encoded_image_callback_ = callback; - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::Release() { - DVLOG(3) << "Release()"; - DCHECK(thread_checker_.CalledOnValidThread()); - - // Reset the gpu_factory_, in case we reuse this encoder. - gpu_factories_->Abort(); - gpu_factories_ = gpu_factories_->Clone(); - if (impl_) { - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); - impl_ = NULL; - weak_this_factory_.reset(); - impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED; - } - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, int rtt) { - DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss - << ", rtt=" << rtt; - DCHECK(thread_checker_.CalledOnValidThread()); - // Ignored. - return WEBRTC_VIDEO_CODEC_OK; -} - -int32_t RTCVideoEncoder::SetRates(uint32_t new_bit_rate, uint32_t frame_rate) { - DVLOG(3) << "SetRates(): new_bit_rate=" << new_bit_rate - << ", frame_rate=" << frame_rate; - DCHECK(thread_checker_.CalledOnValidThread()); - if (!impl_) { - DVLOG(3) << "SetRates(): returning " << impl_status_; - return impl_status_; - } - - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::RequestEncodingParametersChange, - impl_, - new_bit_rate, - frame_rate)); - return WEBRTC_VIDEO_CODEC_OK; -} - -void RTCVideoEncoder::ReturnEncodedImage(scoped_ptr<webrtc::EncodedImage> image, - int32 bitstream_buffer_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - DVLOG(3) << "ReturnEncodedImage(): " - "bitstream_buffer_id=" << bitstream_buffer_id; - - if (!encoded_image_callback_) - return; - - webrtc::CodecSpecificInfo info; - info.codecType = video_codec_type_; - - // Generate a header describing a single fragment. - webrtc::RTPFragmentationHeader header; - header.VerifyAndAllocateFragmentationHeader(1); - header.fragmentationOffset[0] = 0; - header.fragmentationLength[0] = image->_length; - header.fragmentationPlType[0] = 0; - header.fragmentationTimeDiff[0] = 0; - - int32_t retval = encoded_image_callback_->Encoded(*image, &info, &header); - if (retval < 0) { - DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned " - << retval; - } - - // The call through webrtc::EncodedImageCallback is synchronous, so we can - // immediately recycle the output buffer back to the Impl. - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, - base::Bind(&RTCVideoEncoder::Impl::UseOutputBitstreamBufferId, - impl_, - bitstream_buffer_id)); -} - -void RTCVideoEncoder::NotifyError(int32_t error) { - DCHECK(thread_checker_.CalledOnValidThread()); - DVLOG(1) << "NotifyError(): error=" << error; - - impl_status_ = error; - gpu_factories_->GetMessageLoop()->PostTask( - FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); - impl_ = NULL; -} - -} // namespace content diff --git a/chromium/content/renderer/media/rtc_video_encoder.h b/chromium/content/renderer/media/rtc_video_encoder.h deleted file mode 100644 index 22d4c503d3a..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2013 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. - -#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ -#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ - -#include <vector> - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" -#include "base/time/time.h" -#include "content/common/content_export.h" -#include "media/base/video_decoder_config.h" -#include "third_party/webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" -#include "ui/gfx/size.h" - -namespace base { - -class MessageLoopProxy; - -} // namespace base - -namespace content { - -class RendererGpuVideoAcceleratorFactories; - -// RTCVideoEncoder uses a media::VideoEncodeAccelerator to implement a -// webrtc::VideoEncoder class for WebRTC. Internally, VEA methods are -// trampolined to a private RTCVideoEncoder::Impl instance. The Impl class runs -// on the worker thread queried from the |gpu_factories_|, which is presently -// the media thread. RTCVideoEncoder itself is run and destroyed on the thread -// it is constructed on, which is presently the libjingle worker thread. -// Callbacks from the Impl due to its VEA::Client notifications are also posted -// back to RTCVideoEncoder on this thread. -class CONTENT_EXPORT RTCVideoEncoder - : NON_EXPORTED_BASE(public webrtc::VideoEncoder) { - public: - RTCVideoEncoder( - webrtc::VideoCodecType type, - media::VideoCodecProfile profile, - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - virtual ~RTCVideoEncoder(); - - // webrtc::VideoEncoder implementation. Tasks are posted to |impl_| using the - // appropriate VEA methods. - virtual int32_t InitEncode(const webrtc::VideoCodec* codec_settings, - int32_t number_of_cores, - uint32_t max_payload_size) OVERRIDE; - virtual int32_t Encode( - const webrtc::I420VideoFrame& input_image, - const webrtc::CodecSpecificInfo* codec_specific_info, - const std::vector<webrtc::VideoFrameType>* frame_types) OVERRIDE; - virtual int32_t RegisterEncodeCompleteCallback( - webrtc::EncodedImageCallback* callback) OVERRIDE; - virtual int32_t Release() OVERRIDE; - virtual int32_t SetChannelParameters(uint32_t packet_loss, int rtt) OVERRIDE; - virtual int32_t SetRates(uint32_t new_bit_rate, uint32_t frame_rate) OVERRIDE; - - private: - class Impl; - friend class RTCVideoEncoder::Impl; - - // Return an encoded output buffer to WebRTC. - void ReturnEncodedImage(scoped_ptr<webrtc::EncodedImage> image, - int32 bitstream_buffer_id); - - void NotifyError(int32_t error); - - base::ThreadChecker thread_checker_; - - // The video codec type, as reported to WebRTC. - const webrtc::VideoCodecType video_codec_type_; - - // The video codec profile, to configure the encoder to encode to. - const media::VideoCodecProfile video_codec_profile_; - - // Factory for creating VEAs, shared memory buffers, etc. - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // Weak pointer and factory for posting back VEA::Client notifications to - // RTCVideoEncoder. - scoped_ptr<base::WeakPtrFactory<RTCVideoEncoder> > weak_this_factory_; - - // webrtc::VideoEncoder encode complete callback. - webrtc::EncodedImageCallback* encoded_image_callback_; - - // The RTCVideoEncoder::Impl that does all the work. - scoped_refptr<Impl> impl_; - - // We cannot immediately return error conditions to the WebRTC user of this - // class, as there is no error callback in the webrtc::VideoEncoder interface. - // Instead, we cache an error status here and return it the next time an - // interface entry point is called. - int32_t impl_status_; - - DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoder); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_ diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.cc b/chromium/content/renderer/media/rtc_video_encoder_factory.cc deleted file mode 100644 index 3ff42728df2..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder_factory.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 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/renderer/media/rtc_video_encoder_factory.h" - -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" -#include "content/renderer/media/rtc_video_encoder.h" -#include "media/video/video_encode_accelerator.h" - -namespace content { - -namespace { - -// Translate from media::VideoEncodeAccelerator::SupportedProfile to -// cricket::WebRtcVideoEncoderFactory::VideoCodec -cricket::WebRtcVideoEncoderFactory::VideoCodec VEAToWebRTCCodec( - const media::VideoEncodeAccelerator::SupportedProfile& profile) { - webrtc::VideoCodecType type = webrtc::kVideoCodecUnknown; - std::string name; - int width = 0, height = 0, fps = 0; - - if (profile.profile >= media::VP8PROFILE_MIN && - profile.profile <= media::VP8PROFILE_MAX) { - type = webrtc::kVideoCodecVP8; - name = "VP8"; - } else if (profile.profile >= media::H264PROFILE_MIN && - profile.profile <= media::H264PROFILE_MAX) { - type = webrtc::kVideoCodecGeneric; - name = "CAST1"; - } - - if (type != webrtc::kVideoCodecUnknown) { - width = profile.max_resolution.width(); - height = profile.max_resolution.height(); - fps = profile.max_framerate.numerator; - DCHECK_EQ(profile.max_framerate.denominator, 1U); - } - - return cricket::WebRtcVideoEncoderFactory::VideoCodec( - type, name, width, height, fps); -} - -// Translate from cricket::WebRtcVideoEncoderFactory::VideoCodec to -// media::VideoCodecProfile. Pick a default profile for each codec type. -media::VideoCodecProfile WebRTCCodecToVideoCodecProfile( - webrtc::VideoCodecType type) { - switch (type) { - case webrtc::kVideoCodecVP8: - return media::VP8PROFILE_MAIN; - case webrtc::kVideoCodecGeneric: - return media::H264PROFILE_MAIN; - default: - return media::VIDEO_CODEC_PROFILE_UNKNOWN; - } -} - -} // anonymous namespace - -RTCVideoEncoderFactory::RTCVideoEncoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) - : gpu_factories_(gpu_factories) { - // Query media::VideoEncodeAccelerator (statically) for our supported codecs. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles = - GpuVideoEncodeAcceleratorHost::GetSupportedProfiles(); - for (size_t i = 0; i < profiles.size(); ++i) { - VideoCodec codec = VEAToWebRTCCodec(profiles[i]); - if (codec.type != webrtc::kVideoCodecUnknown) - codecs_.push_back(codec); - } -} - -RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {} - -webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder( - webrtc::VideoCodecType type) { - bool found = false; - for (size_t i = 0; i < codecs_.size(); ++i) { - if (codecs_[i].type == type) { - found = true; - break; - } - } - if (!found) - return NULL; - // GpuVideoAcceleratorFactories is not thread safe. It cannot be shared - // by different encoders. Since we aren't running on the child thread and - // cannot create a new factory, clone one instead. - return new RTCVideoEncoder( - type, WebRTCCodecToVideoCodecProfile(type), gpu_factories_->Clone()); -} - -void RTCVideoEncoderFactory::AddObserver(Observer* observer) { - // No-op: our codec list is populated on installation. -} - -void RTCVideoEncoderFactory::RemoveObserver(Observer* observer) {} - -const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>& -RTCVideoEncoderFactory::codecs() const { - return codecs_; -} - -void RTCVideoEncoderFactory::DestroyVideoEncoder( - webrtc::VideoEncoder* encoder) { - delete encoder; -} - -} // namespace content diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.h b/chromium/content/renderer/media/rtc_video_encoder_factory.h deleted file mode 100644 index b07ccda0043..00000000000 --- a/chromium/content/renderer/media/rtc_video_encoder_factory.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013 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. - -#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ -#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ - -#include <vector> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoencoderfactory.h" - -namespace content { - -class RendererGpuVideoAcceleratorFactories; - -// This class creates RTCVideoEncoder instances (each wrapping a -// media::VideoEncodeAccelerator) on behalf of the WebRTC stack. -class CONTENT_EXPORT RTCVideoEncoderFactory - : NON_EXPORTED_BASE(public cricket::WebRtcVideoEncoderFactory) { - public: - explicit RTCVideoEncoderFactory( - const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); - virtual ~RTCVideoEncoderFactory(); - - // cricket::WebRtcVideoEncoderFactory implementation. - virtual webrtc::VideoEncoder* CreateVideoEncoder( - webrtc::VideoCodecType type) OVERRIDE; - virtual void AddObserver(Observer* observer) OVERRIDE; - virtual void RemoveObserver(Observer* observer) OVERRIDE; - virtual const std::vector<VideoCodec>& codecs() const OVERRIDE; - virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) OVERRIDE; - - private: - const scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; - - // Codec support list of cricket::WebRtcVideoEncoderFactory::VideoCodec - // instances. - std::vector<VideoCodec> codecs_; - - DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_ diff --git a/chromium/content/renderer/media/webmediaplayer_impl.cc b/chromium/content/renderer/media/webmediaplayer_impl.cc index d4780970eb4..227d0cf4b14 100644 --- a/chromium/content/renderer/media/webmediaplayer_impl.cc +++ b/chromium/content/renderer/media/webmediaplayer_impl.cc @@ -43,8 +43,8 @@ #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_video_decoder.h" -#include "media/filters/gpu_video_accelerator_factories.h" #include "media/filters/gpu_video_decoder.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "media/filters/opus_audio_decoder.h" #include "media/filters/video_renderer_base.h" #include "media/filters/vpx_video_decoder.h" diff --git a/chromium/content/renderer/media/webmediaplayer_impl.h b/chromium/content/renderer/media/webmediaplayer_impl.h index c386b08f2b0..23b1ddf524a 100644 --- a/chromium/content/renderer/media/webmediaplayer_impl.h +++ b/chromium/content/renderer/media/webmediaplayer_impl.h @@ -56,7 +56,7 @@ class MessageLoopProxy; namespace media { class ChunkDemuxer; class FFmpegDemuxer; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; class MediaLog; } @@ -318,8 +318,8 @@ class WebMediaPlayerImpl bool incremented_externally_allocated_memory_; - // Factories for supporting video accelerators. May be null. - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_; + // Factories for supporting GpuVideoDecoder. May be null. + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories_; // Routes audio playback to either AudioRendererSink or WebAudio. scoped_refptr<WebAudioSourceProviderImpl> audio_source_provider_; diff --git a/chromium/content/renderer/media/webmediaplayer_params.cc b/chromium/content/renderer/media/webmediaplayer_params.cc index a05abbfa571..04fe3105736 100644 --- a/chromium/content/renderer/media/webmediaplayer_params.cc +++ b/chromium/content/renderer/media/webmediaplayer_params.cc @@ -7,7 +7,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "media/base/audio_renderer_sink.h" #include "media/base/media_log.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" namespace content { @@ -15,7 +15,7 @@ WebMediaPlayerParams::WebMediaPlayerParams( const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, const base::Callback<void(const base::Closure&)>& defer_load_cb, const scoped_refptr<media::AudioRendererSink>& audio_renderer_sink, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories, + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories, const scoped_refptr<media::MediaLog>& media_log) : message_loop_proxy_(message_loop_proxy), defer_load_cb_(defer_load_cb), diff --git a/chromium/content/renderer/media/webmediaplayer_params.h b/chromium/content/renderer/media/webmediaplayer_params.h index bf398642f77..4347a4af460 100644 --- a/chromium/content/renderer/media/webmediaplayer_params.h +++ b/chromium/content/renderer/media/webmediaplayer_params.h @@ -14,7 +14,7 @@ class MessageLoopProxy; namespace media { class AudioRendererSink; -class GpuVideoAcceleratorFactories; +class GpuVideoDecoderFactories; class MediaLog; } @@ -30,7 +30,7 @@ class WebMediaPlayerParams { const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, const base::Callback<void(const base::Closure&)>& defer_load_cb, const scoped_refptr<media::AudioRendererSink>& audio_renderer_sink, - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories, + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories, const scoped_refptr<media::MediaLog>& media_log); ~WebMediaPlayerParams(); @@ -46,8 +46,7 @@ class WebMediaPlayerParams { return audio_renderer_sink_; } - const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories() - const { + const scoped_refptr<media::GpuVideoDecoderFactories>& gpu_factories() const { return gpu_factories_; } @@ -59,7 +58,7 @@ class WebMediaPlayerParams { scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; base::Callback<void(const base::Closure&)> defer_load_cb_; scoped_refptr<media::AudioRendererSink> audio_renderer_sink_; - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_; + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories_; scoped_refptr<media::MediaLog> media_log_; DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerParams); diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.cc b/chromium/content/renderer/media/webrtc_audio_device_impl.cc index c40e0a2219b..254561e4ae1 100644 --- a/chromium/content/renderer/media/webrtc_audio_device_impl.cc +++ b/chromium/content/renderer/media/webrtc_audio_device_impl.cc @@ -63,7 +63,9 @@ int WebRtcAudioDeviceImpl::CaptureData(const std::vector<int>& channels, int total_delay_ms = 0; { base::AutoLock auto_lock(lock_); - if (!recording_) + // Return immediately when not recording or |channels| is empty. + // See crbug.com/274017: renderer crash dereferencing invalid channels[0]. + if (!recording_ || channels.empty()) return 0; // Store the reported audio delay locally. diff --git a/chromium/content/renderer/media/webrtc_local_audio_track.cc b/chromium/content/renderer/media/webrtc_local_audio_track.cc index de86a3c4cc3..1aae3056f6d 100644 --- a/chromium/content/renderer/media/webrtc_local_audio_track.cc +++ b/chromium/content/renderer/media/webrtc_local_audio_track.cc @@ -34,6 +34,12 @@ WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( // and APM (AudioProcessingModule) is turned on only for microphone data. DCHECK(capturer.get()); DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()"; + + // TODO(tommi): Remove this, feed audio constraints to WebRtcLocalAudioTrack + // and check the constraints. This is here to fix a recent regression whereby + // audio processing is not enabled for WebAudio regardless of the hard coded + // audio constraints. For more info: http://crbug.com/277134 + need_audio_processing_ = true; } WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { diff --git a/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc b/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc index 4720e45bf01..776cbb10035 100644 --- a/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc +++ b/chromium/content/renderer/media/webrtc_local_audio_track_unittest.cc @@ -175,7 +175,7 @@ TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) { EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink, CaptureData( kNumberOfNetworkChannels, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); track->AddSink(sink.get()); @@ -245,7 +245,7 @@ TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink_1, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); track_1->AddSink(sink_1.get()); EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); @@ -266,11 +266,11 @@ TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); EXPECT_CALL(*sink_1, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); EXPECT_CALL(*sink_2, CaptureData( 1, params.sample_rate(), params.channels(), - params.frames_per_buffer(), 0, 0, false)) + params.frames_per_buffer(), 0, 0, _)) .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); track_2->AddSink(sink_2.get()); EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); @@ -319,7 +319,7 @@ TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { scoped_ptr<MockWebRtcAudioCapturerSink> sink( new MockWebRtcAudioCapturerSink()); event.Reset(); - EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false)) + EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, _)) .Times(AnyNumber()).WillRepeatedly(Return()); EXPECT_CALL(*sink, SetCaptureFormat(_)).Times(1); track_1->AddSink(sink.get()); @@ -397,7 +397,7 @@ TEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) { scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( new MockWebRtcAudioCapturerSink()); EXPECT_CALL(*sink_1.get(), CaptureData(kNumberOfNetworkChannelsForTrack1, - 48000, 2, _, 0, 0, false)) + 48000, 2, _, 0, 0, _)) .Times(AnyNumber()).WillRepeatedly(Return()); EXPECT_CALL(*sink_1.get(), SetCaptureFormat(_)).Times(1); track_1->AddSink(sink_1.get()); diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.cc b/chromium/content/renderer/pepper/pepper_in_process_router.cc index d5c0d429a40..1446426dd77 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.cc +++ b/chromium/content/renderer/pepper/pepper_in_process_router.cc @@ -110,9 +110,24 @@ bool PepperInProcessRouter::SendToHost(IPC::Message* msg) { scoped_ptr<IPC::Message> message(msg); if (!message->is_sync()) { - bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); - DCHECK(result) << "The message was not handled by the host."; - return true; + // If this is a resource destroyed message, post a task to dispatch it. + // Dispatching it synchronously can cause the host to re-enter the proxy + // code while we're still in the resource destructor, leading to a crash. + // http://crbug.com/276368. + // This won't cause message reordering problems because the resource + // destroyed message is always the last one sent for a resource. + if (message->type() == PpapiHostMsg_ResourceDestroyed::ID) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&PepperInProcessRouter::DispatchHostMsg, + weak_factory_.GetWeakPtr(), + base::Owned(message.release()))); + return true; + } else { + bool result = host_impl_->GetPpapiHost()->OnMessageReceived(*message); + DCHECK(result) << "The message was not handled by the host."; + return true; + } } pending_message_id_ = IPC::SyncMessage::GetMessageId(*message); @@ -146,6 +161,11 @@ bool PepperInProcessRouter::SendToPlugin(IPC::Message* msg) { return true; } +void PepperInProcessRouter::DispatchHostMsg(IPC::Message* msg) { + bool handled = host_impl_->GetPpapiHost()->OnMessageReceived(*msg); + DCHECK(handled); +} + void PepperInProcessRouter::DispatchPluginMsg(IPC::Message* msg) { bool handled = OnPluginMsgReceived(*msg); DCHECK(handled); diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.h b/chromium/content/renderer/pepper/pepper_in_process_router.h index 568c18eaab4..77b19881174 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.h +++ b/chromium/content/renderer/pepper/pepper_in_process_router.h @@ -71,6 +71,7 @@ class PepperInProcessRouter { private: bool SendToHost(IPC::Message *msg); bool SendToPlugin(IPC::Message *msg); + void DispatchHostMsg(IPC::Message* msg); void DispatchPluginMsg(IPC::Message* msg); bool SendToBrowser(IPC::Message *msg); diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc index 8343f1934ea..9b951f57354 100644 --- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc +++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc @@ -249,9 +249,12 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( WebFrame* frame = GetFrame(); if (!frame) return PP_ERROR_FAILED; + WebURLRequest web_request; if (!CreateWebURLRequest(&filled_in_request_data, frame, &web_request)) return PP_ERROR_FAILED; + + web_request.setTargetType(WebURLRequest::TargetIsObject); web_request.setRequestorProcessID(renderer_ppapi_host_->GetPluginPID()); WebURLLoaderOptions options; diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc index e82c8a18612..72365fde336 100644 --- a/chromium/content/renderer/pepper/url_request_info_util.cc +++ b/chromium/content/renderer/pepper/url_request_info_util.cc @@ -124,7 +124,6 @@ bool CreateWebURLRequest(ppapi::URLRequestInfoData* data, return false; dest->initialize(); - dest->setTargetType(WebURLRequest::TargetIsObject); dest->setURL(frame->document().completeURL(WebString::fromUTF8( data->url))); dest->setDownloadToFile(data->stream_to_file); diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index 92bfb3d6a3c..fff52e0ff96 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -274,6 +274,17 @@ void RenderFrameImpl::loadURLExternally( WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( WebKit::WebFrame* frame, + WebKit::WebDataSource::ExtraData* extra_data, + const WebKit::WebURLRequest& request, + WebKit::WebNavigationType type, + WebKit::WebNavigationPolicy default_policy, + bool is_redirect) { + return render_view_->decidePolicyForNavigation( + frame, extra_data, request, type, default_policy, is_redirect); +} + +WebKit::WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( + WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, WebKit::WebNavigationType type, WebKit::WebNavigationPolicy default_policy, diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h index f4686b2d15d..f64a5230455 100644 --- a/chromium/content/renderer/render_frame_impl.h +++ b/chromium/content/renderer/render_frame_impl.h @@ -71,6 +71,14 @@ class CONTENT_EXPORT RenderFrameImpl const WebKit::WebString& suggested_name); virtual WebKit::WebNavigationPolicy decidePolicyForNavigation( WebKit::WebFrame* frame, + WebKit::WebDataSource::ExtraData* extra_data, + const WebKit::WebURLRequest& request, + WebKit::WebNavigationType type, + WebKit::WebNavigationPolicy default_policy, + bool is_redirect); + // DEPRECATED + virtual WebKit::WebNavigationPolicy decidePolicyForNavigation( + WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, WebKit::WebNavigationType type, WebKit::WebNavigationPolicy default_policy, diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc index f15738dd00a..b1e4a71cd6f 100644 --- a/chromium/content/renderer/render_thread_impl.cc +++ b/chromium/content/renderer/render_thread_impl.cc @@ -87,7 +87,7 @@ #include "ipc/ipc_platform_file.h" #include "media/base/audio_hardware_config.h" #include "media/base/media.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -887,20 +887,22 @@ void RenderThreadImpl::PostponeIdleNotification() { idle_notifications_to_skip_ = 2; } -scoped_refptr<RendererGpuVideoAcceleratorFactories> +scoped_refptr<RendererGpuVideoDecoderFactories> RenderThreadImpl::GetGpuFactories( const scoped_refptr<base::MessageLoopProxy>& factories_loop) { DCHECK(IsMainThread()); const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories; + scoped_refptr<RendererGpuVideoDecoderFactories> gpu_factories; WebGraphicsContext3DCommandBufferImpl* context3d = NULL; if (!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) context3d = GetGpuVDAContext3D(); - GpuChannelHost* gpu_channel_host = GetGpuChannel(); - if (gpu_channel_host) { - gpu_factories = new RendererGpuVideoAcceleratorFactories( - gpu_channel_host, factories_loop, context3d); + if (context3d) { + GpuChannelHost* gpu_channel_host = GetGpuChannel(); + if (gpu_channel_host) { + gpu_factories = new RendererGpuVideoDecoderFactories( + gpu_channel_host, factories_loop, context3d); + } } return gpu_factories; } diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h index d11a4989557..fd2cfff7f42 100644 --- a/chromium/content/renderer/render_thread_impl.h +++ b/chromium/content/renderer/render_thread_impl.h @@ -19,7 +19,7 @@ #include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/gpu_process_launch_causes.h" #include "content/public/renderer/render_thread.h" -#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" +#include "content/renderer/media/renderer_gpu_video_decoder_factories.h" #include "ipc/ipc_channel_proxy.h" #include "ui/gfx/native_widget_types.h" @@ -55,6 +55,7 @@ class ForwardingMessageFilter; namespace media { class AudioHardwareConfig; +class GpuVideoDecoderFactories; } namespace v8 { @@ -257,8 +258,9 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, // not sent for at least one notification delay. void PostponeIdleNotification(); - // Gets gpu factories, which will run on |factories_loop|. - scoped_refptr<RendererGpuVideoAcceleratorFactories> GetGpuFactories( + // Gets gpu factories, which will run on |factories_loop|. Returns NULL if VDA + // is disabled or a graphics context cannot be obtained. + scoped_refptr<RendererGpuVideoDecoderFactories> GetGpuFactories( const scoped_refptr<base::MessageLoopProxy>& factories_loop); // Returns a graphics context shared among all diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc index 125f4c3214d..c400a749677 100644 --- a/chromium/content/renderer/render_view_browsertest.cc +++ b/chromium/content/renderer/render_view_browsertest.cc @@ -771,7 +771,10 @@ TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) { // Test that our IME backend sends a notification message when the input focus // changes. -TEST_F(RenderViewImplTest, OnImeTypeChanged) { +// crbug.com/276821: +// Because Blink change cause this test failed, we first disabled this test and +// fix later. +TEST_F(RenderViewImplTest, DISABLED_OnImeTypeChanged) { // Enable our IME backend code. view()->OnSetInputMethodActive(true); diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc index d64150c58ab..1df467e88f2 100644 --- a/chromium/content/renderer/render_view_impl.cc +++ b/chromium/content/renderer/render_view_impl.cc @@ -132,7 +132,7 @@ #include "media/base/filter_collection.h" #include "media/base/media_switches.h" #include "media/filters/audio_renderer_impl.h" -#include "media/filters/gpu_video_accelerator_factories.h" +#include "media/filters/gpu_video_decoder_factories.h" #include "net/base/data_url.h" #include "net/base/escape.h" #include "net/base/net_errors.h" @@ -2290,6 +2290,7 @@ WebView* RenderViewImpl::createView( params.frame_name = frame_name; params.opener_frame_id = creator->identifier(); params.opener_url = creator->document().url(); + params.opener_top_level_frame_url = creator->top()->document().url(); GURL security_url(creator->document().securityOrigin().toString().utf8()); if (!security_url.is_valid()) security_url = GURL(); @@ -2687,10 +2688,6 @@ void RenderViewImpl::showContextMenu( RenderViewObserver, observers_, DidRequestShowContextMenu(frame, data)); } -void RenderViewImpl::clearContextMenu() { - context_menu_node_.reset(); -} - void RenderViewImpl::setStatusText(const WebString& text) { } @@ -2993,7 +2990,7 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( #if defined(ENABLE_WEBRTC) EnsureMediaStreamClient(); #if !defined(GOOGLE_TV) - if (media_stream_client_->IsMediaStream(url)) { + if (media_stream_client_ && media_stream_client_->IsMediaStream(url)) { #if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL) bool found_neon = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; @@ -3071,7 +3068,7 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer( DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink.get(); } - scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories = + scoped_refptr<media::GpuVideoDecoderFactories> gpu_factories = RenderThreadImpl::current()->GetGpuFactories( RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()); @@ -4235,13 +4232,17 @@ bool RenderViewImpl::ShouldUpdateSelectionTextFromContextMenuParams( void RenderViewImpl::reportFindInPageMatchCount(int request_id, int count, bool final_update) { - NOTREACHED(); + // TODO(jam): switch PepperPluginInstanceImpl to take a RenderFrame + main_render_frame_->reportFindInPageMatchCount( + request_id, count, final_update); } void RenderViewImpl::reportFindInPageSelection(int request_id, int active_match_ordinal, const WebRect& selection_rect) { - NOTREACHED(); + // TODO(jam): switch PepperPluginInstanceImpl to take a RenderFrame + main_render_frame_->reportFindInPageSelection( + request_id, active_match_ordinal, selection_rect); } void RenderViewImpl::openFileSystem( diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h index d338b172a7e..4c6d77acb36 100644 --- a/chromium/content/renderer/render_view_impl.h +++ b/chromium/content/renderer/render_view_impl.h @@ -484,7 +484,6 @@ class CONTENT_EXPORT RenderViewImpl const WebKit::WebString& message); virtual void showContextMenu(WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data); - virtual void clearContextMenu(); virtual void setStatusText(const WebKit::WebString& text); virtual void setMouseOverURL(const WebKit::WebURL& url); virtual void setKeyboardFocusURL(const WebKit::WebURL& url); @@ -1091,6 +1090,9 @@ class CONTENT_EXPORT RenderViewImpl void CheckPreferredSize(); // Initializes |media_stream_client_| if needed. + // TODO(qinmin): rename this function as it does not guarantee + // |media_stream_client_| will be created. + // http://crbug.com/278490. void EnsureMediaStreamClient(); // This callback is triggered when DownloadFavicon completes, either diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc index 5fe9a9a2176..0a8b0d84bfc 100644 --- a/chromium/content/renderer/renderer_main.cc +++ b/chromium/content/renderer/renderer_main.cc @@ -181,6 +181,8 @@ int RendererMain(const MainFunctionParams& parameters) { base::FieldTrialList field_trial_list(NULL); // Ensure any field trials in browser are reflected into renderer. if (parsed_command_line.HasSwitch(switches::kForceFieldTrials)) { + std::string persistent = parsed_command_line.GetSwitchValueASCII( + switches::kForceFieldTrials); // Field trials are created in an "activated" state to ensure they get // reported in crash reports. bool result = base::FieldTrialList::CreateTrialsFromString( diff --git a/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc b/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc index fd07f28ce95..d5156a1d350 100644 --- a/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc +++ b/chromium/content/renderer/renderer_webkitplatformsupport_impl.cc @@ -148,6 +148,8 @@ class RendererWebKitPlatformSupportImpl::MimeRegistry const WebKit::WebString& file_extension); virtual WebKit::WebString mimeTypeFromFile( const WebKit::WebString& file_path); + virtual WebKit::WebString preferredExtensionForMIMEType( + const WebKit::WebString& mime_type); }; class RendererWebKitPlatformSupportImpl::FileUtilities @@ -223,10 +225,6 @@ RendererWebKitPlatformSupportImpl::RendererWebKitPlatformSupportImpl() } RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - WebFileSystemImpl::DeleteThreadSpecificInstance(); -#endif } //------------------------------------------------------------------------------ @@ -376,14 +374,9 @@ WebIDBFactory* RendererWebKitPlatformSupportImpl::idbFactory() { //------------------------------------------------------------------------------ WebFileSystem* RendererWebKitPlatformSupportImpl::fileSystem() { -#ifdef USE_THREADLOCAL_WEBFILESYSTEM - // TODO(kinuko): Delete this ifdef after blink side switch's over. - return WebFileSystemImpl::ThreadSpecificInstance(child_thread_loop_.get()); -#else if (!web_file_system_) web_file_system_.reset(new WebFileSystemImpl(child_thread_loop_.get())); return web_file_system_.get(); -#endif } //------------------------------------------------------------------------------ @@ -491,6 +484,21 @@ WebString RendererWebKitPlatformSupportImpl::MimeRegistry::mimeTypeFromFile( return ASCIIToUTF16(mime_type); } +WebString +RendererWebKitPlatformSupportImpl::MimeRegistry::preferredExtensionForMIMEType( + const WebString& mime_type) { + if (IsPluginProcess()) + return SimpleWebMimeRegistryImpl::preferredExtensionForMIMEType(mime_type); + + // The sandbox restricts our access to the registry, so we need to proxy + // these calls over to the browser process. + base::FilePath::StringType file_extension; + RenderThread::Get()->Send( + new MimeRegistryMsg_GetPreferredExtensionForMimeType( + UTF16ToASCII(mime_type), &file_extension)); + return base::FilePath(file_extension).AsUTF16Unsafe(); +} + //------------------------------------------------------------------------------ bool RendererWebKitPlatformSupportImpl::FileUtilities::getFileInfo( diff --git a/chromium/content/renderer/rendering_benchmark.cc b/chromium/content/renderer/rendering_benchmark.cc new file mode 100644 index 00000000000..5415bdd7d8f --- /dev/null +++ b/chromium/content/renderer/rendering_benchmark.cc @@ -0,0 +1,12 @@ +// Copyright (c) 2012 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/renderer/rendering_benchmark.h" + +namespace content { + +RenderingBenchmark::RenderingBenchmark(const std::string& name) : name_(name) {} +RenderingBenchmark::~RenderingBenchmark() {} + +} // namespace content diff --git a/chromium/content/renderer/rendering_benchmark.h b/chromium/content/renderer/rendering_benchmark.h new file mode 100644 index 00000000000..44b5a84d79a --- /dev/null +++ b/chromium/content/renderer/rendering_benchmark.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 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. + +#ifndef CONTENT_RENDERER_RENDERING_BENCHMARK_H_ +#define CONTENT_RENDERER_RENDERING_BENCHMARK_H_ + +#include <string> + +#include "base/basictypes.h" + +namespace WebKit { +class WebViewBenchmarkSupport; +} + +namespace content { +class RenderingBenchmarkResults; + +class RenderingBenchmark { + public: + explicit RenderingBenchmark(const std::string& name); + virtual ~RenderingBenchmark(); + + virtual void SetUp(WebKit::WebViewBenchmarkSupport* benchmarkSupport) {} + + virtual double Run(WebKit::WebViewBenchmarkSupport* benchmarkSupport) = 0; + + virtual void TearDown(WebKit::WebViewBenchmarkSupport* benchmarkSupport) {} + + const std::string& name() { return name_; } + + private: + const std::string name_; + + DISALLOW_COPY_AND_ASSIGN(RenderingBenchmark); +}; +} // namespace content + +#endif // CONTENT_RENDERER_RENDERING_BENCHMARK_H_ |