OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/gpu/android_video_surface_chooser_impl.h" | |
6 | |
7 namespace media { | |
8 | |
9 AndroidVideoSurfaceChooserImpl::AndroidVideoSurfaceChooserImpl() | |
10 : weak_factory_(this) {} | |
11 | |
12 AndroidVideoSurfaceChooserImpl::~AndroidVideoSurfaceChooserImpl() {} | |
13 | |
14 void AndroidVideoSurfaceChooserImpl::Initialize( | |
15 UseOverlayCB use_overlay_cb, | |
16 UseSurfaceTextureCB use_surface_texture_cb, | |
17 StopUsingOverlayImmediatelyCB stop_immediately_cb, | |
18 std::unique_ptr<AndroidOverlayFactory> initial_factory) { | |
19 use_overlay_cb_ = std::move(use_overlay_cb); | |
20 use_surface_texture_cb_ = std::move(use_surface_texture_cb); | |
21 stop_immediately_cb_ = std::move(stop_immediately_cb); | |
22 | |
23 if (initial_factory) { | |
24 // We requested an overlay. Wait to see if it succeeds or fails, since | |
25 // hopefully this will be fast. On M+, we could ask it to start with a | |
26 // SurfaceTexture either way. Before M, we can't switch surfaces. In that | |
27 // case, it's important not to request a SurfaceTexture if we have an | |
28 // overlay pending, so that we know not to transition to SurfaceTexture. | |
29 client_notification_pending_ = true; | |
30 ReplaceOverlayFactory(std::move(initial_factory)); | |
31 } | |
32 | |
33 if (!overlay_) { | |
34 // We haven't requested an overlay yet. Just ask the client to start with | |
35 // SurfaceTexture now. | |
36 use_surface_texture_cb_.Run(); | |
37 return; | |
38 } | |
39 } | |
40 | |
41 void AndroidVideoSurfaceChooserImpl::ReplaceOverlayFactory( | |
42 std::unique_ptr<AndroidOverlayFactory> factory) { | |
43 // If we have an overlay, then we should transition away from it. It | |
44 // doesn't matter if we have a new factory or no factory; the old overlay goes | |
45 // with the old factory. | |
46 | |
47 // Notify the client to transition to SurfaceTexture, which it might already | |
48 // be using. If |!client_notification_pending_|, then we're still during | |
49 // initial startup, so we don't switch the client. Otherwise, we'd cause | |
50 // pre-M to break, since we'd start with a SurfaceTexture in all cases. | |
51 if (!client_notification_pending_) | |
52 use_surface_texture_cb_.Run(); | |
53 | |
54 // If we started construction of an overlay, but it's not ready yet, then | |
55 // just drop it. | |
56 if (overlay_) | |
57 overlay_ = nullptr; | |
58 | |
59 overlay_factory_ = std::move(factory); | |
60 | |
61 // If we don't have a new factory, then just stop here. | |
62 if (!overlay_factory_) | |
63 return; | |
64 | |
65 // We just got an overlay factory. Get an overlay immediately. This is | |
66 // the right behavior to match what AVDA does with CVV. For DS, we should | |
67 // probably check to see if it's a good idea, at least on M+. | |
68 // Also note that for pre-M, AVDA depends on this behavior, else it will get | |
69 // a SurfaceTexture then be unable to switch. Perhaps there should be a | |
70 // pre-M implementation of this class that guarantees that it won't change | |
71 // between the two. | |
72 AndroidOverlay::Config config; | |
73 // We bind all of our callbacks with weak ptrs, since we don't know how long | |
74 // the client will hold on to overlays. They could, in principle, show up | |
75 // long after the client is destroyed too, if codec destruction hangs. | |
76 config.ready_cb = base::Bind(&AndroidVideoSurfaceChooserImpl::OnOverlayReady, | |
77 weak_factory_.GetWeakPtr()); | |
78 config.failed_cb = | |
79 base::Bind(&AndroidVideoSurfaceChooserImpl::OnOverlayFailed, | |
80 weak_factory_.GetWeakPtr()); | |
81 config.destroyed_cb = | |
82 base::Bind(&AndroidVideoSurfaceChooserImpl::OnSurfaceDestroyed, | |
83 weak_factory_.GetWeakPtr()); | |
84 // TODO(liberato): where do we get the initial size from? For CVV, it's | |
85 // set via the natural size, and this is ignored anyway. The client should | |
86 // provide this. | |
87 config.rect = gfx::Rect(0, 0, 1, 1); | |
88 overlay_ = overlay_factory_->CreateOverlay(config); | |
89 } | |
90 | |
91 void AndroidVideoSurfaceChooserImpl::OnOverlayReady(AndroidOverlay* overlay) { | |
92 // We |overlay_| is the only overlay for which we haven't gotten a ready | |
watk
2017/05/02 21:00:01
The "We" needs deleting?
liberato (no reviews please)
2017/05/02 21:50:05
Done.
| |
93 // callback yet. | |
94 DCHECK_EQ(overlay, overlay_.get()); | |
95 | |
96 // If we haven't sent the client notification yet, we're doing so now. | |
97 client_notification_pending_ = false; | |
98 | |
99 use_overlay_cb_.Run(std::move(overlay_)); | |
100 } | |
101 | |
102 void AndroidVideoSurfaceChooserImpl::OnOverlayFailed(AndroidOverlay* overlay) { | |
103 // We shouldn't get a failure for any overlay except the incoming one. | |
104 DCHECK_EQ(overlay, overlay_.get()); | |
105 | |
106 // If we owe the client a notification callback, then send it. | |
107 if (client_notification_pending_) { | |
108 // The overlay that we requested failed, so notify the client to try | |
109 // using SurfaceTexture instead. | |
110 client_notification_pending_ = false; | |
111 use_surface_texture_cb_.Run(); | |
112 } | |
113 | |
114 overlay_ = nullptr; | |
115 } | |
116 | |
117 void AndroidVideoSurfaceChooserImpl::OnSurfaceDestroyed( | |
118 AndroidOverlay* overlay) { | |
119 // We shouldn't get OnSurfaceDestroyed unless we previously got Ready. In | |
120 // that case, we should have notified the client then. | |
121 DCHECK(!client_notification_pending_); | |
122 | |
123 // We should not get OnSurfaceDestroyed for the incoming overlay, since we | |
124 // should't get OnSurfaceDestroyed before OnSurfaceReady. OnSurfaceReady | |
125 // should imply that this isn't the incoming overlay. | |
126 DCHECK_NE(overlay_.get(), overlay); | |
127 | |
128 // We unconditionally send 'stop immediately', since we don't know what | |
129 // overlay this is. Even if we revoked the overlay before, we may have done | |
130 // so with the slow transition, which isn't good enough now. The client has | |
131 // to be smart enoug to understand if it's currently using |overlay| or not. | |
132 | |
133 // Also remember that we don't know when the client drops the overlay, after | |
134 // we revoke it. We can get callbacks until that happens, even if (for | |
135 // example), the overlay is waiting for MediaCodec destruction. So, it's | |
136 // likely that we'll send callbacks for overlays that the client is already | |
137 // not using. | |
138 stop_immediately_cb_.Run(overlay); | |
139 } | |
140 | |
141 } // namespace media | |
OLD | NEW |