Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: media/gpu/avda_overlay_helper_impl.cc

Issue 2813303003: Add AndroidVideoSurfaceChooser to manage overlays. (Closed)
Patch Set: gn fixes for non-android Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/avda_overlay_helper_impl.h"
6
7 namespace media {
8
9 AVDAOverlayHelperImpl::AVDAOverlayHelperImpl() : weak_factory_(this) {}
10
11 AVDAOverlayHelperImpl::~AVDAOverlayHelperImpl() {}
12
13 void AVDAOverlayHelperImpl::Startup(
14 const UseOverlayCB& use_overlay_cb,
15 const UseSurfaceTextureCB& use_surface_texture_cb,
16 const StopUsingOverlayImmediatelyCB& stop_immediately_cb,
17 std::unique_ptr<AndroidOverlayFactory> initial_factory) {
18 use_overlay_cb_ = use_overlay_cb;
19 use_surface_texture_cb_ = use_surface_texture_cb;
20 stop_immediately_cb_ = stop_immediately_cb;
21
22 if (initial_factory) {
23 // We requested an overlay. Wait to see if it succeeds or fails, since
24 // hopefully this will be fast. On M+, we could ask it to start with a
25 // SurfaceTexture either way. Before M, we can't switch surfaces. In that
26 // case, it's important not to request a SurfaceTexture if we have an
27 // overlay pending, so that we know not to transition to SurfaceTexture.
28 client_notification_pending_ = true;
29 OnOverlayFactory(std::move(initial_factory));
30 }
31
32 if (!overlay_) {
33 // We haven't requested an overlay yet. Just ask the client to start with
34 // SurfaceTexture now.
35 use_surface_texture_cb_.Run();
36 return;
37 }
38 }
39
40 void AVDAOverlayHelperImpl::OnOverlayFactory(
41 std::unique_ptr<AndroidOverlayFactory> factory) {
42 // If we have an overlay, then we should transition away from it. It
43 // doesn't matter if we have a new factory or no factory; the old overlay goes
44 // with the old factory.
45
46 // Notify the client to transition to SurfaceTexture, which it might already
47 // be using. If |!client_notification_pending_|, then we're still during
48 // initial startup, so we don't switch the client. Otherwise, we'd cause
49 // pre-M to break, since we'd start with a SurfaceTexture in all cases.
50 // TODO(liberato): should we switch immediately away, at least for CVV, if
51 // |!factory|? It means that we're probably leaving full screen.
52 // We don't do this just to match previous behavior, which always went through
53 // AVDA::SetSurface, which was the slower transition. However, the CVV
54 // won't be visible soon, so maybe that's the wrong thing to do. For DS,
55 // it would be fine to transition slower to avoid dropping frames. Note
56 // that we'd have to not only remember the most recent overlay that we sent
57 // to the client, but we'd also have to find out when the client drops it.
58 // We'd have a raw ptr only, which might be re-used.
59 if (!client_notification_pending_)
60 use_surface_texture_cb_.Run();
61
62 // If we started construction of an overlay, but it's not ready yet, then
63 // just drop it.
64 if (overlay_)
65 overlay_ = nullptr;
66
67 overlay_factory_ = std::move(factory);
68
69 // If we don't have a new factory, then just stop here.
70 if (!overlay_factory_)
71 return;
72
73 // We just got an overlay factory. Get an overlay immediately. This is
74 // the right behavior to match what AVDA does with CVV. For DS, we should
75 // probably check to see if it's a good idea, at least on M+.
76 // Also note that for pre-M, AVDA depends on this behavior, else it will get
77 // a SurfaceTexture then be unable to switch. Perhaps there should be a
78 // pre-M implementation of this class that guarantees that it won't change
79 // between the two.
80 AndroidOverlay::Config config;
81 // We bind all of our callbacks with weak ptrs, since we don't know how long
82 // the client will hold on to overlays. They could, in principle, show up
83 // long after the client is destroyed too, if codec destruction hangs.
84 config.ready_cb = base::Bind(&AVDAOverlayHelperImpl::OnOverlayReady,
85 weak_factory_.GetWeakPtr());
86 config.failed_cb = base::Bind(&AVDAOverlayHelperImpl::OnOverlayFailed,
87 weak_factory_.GetWeakPtr());
88 config.destroyed_cb = base::Bind(&AVDAOverlayHelperImpl::OnSurfaceDestroyed,
89 weak_factory_.GetWeakPtr());
90 // TODO(liberato): where do we get the initial size from? For CVV, it's
91 // set via the natural size, and this is ignored anyway. The client should
92 // provide this.
93 config.rect = gfx::Rect(0, 0, 1, 1);
94 overlay_ = overlay_factory_->CreateOverlay(config);
95 }
96
97 void AVDAOverlayHelperImpl::OnOverlayReady(AndroidOverlay* overlay) {
98 // We |overlay_| is the only overlay for which we haven't gotten a ready
99 // callback yet.
100 DCHECK_EQ(overlay, overlay_.get());
101
102 // If we haven't sent the client notification yet, we're doing so now.
103 client_notification_pending_ = false;
104
105 use_overlay_cb_.Run(std::move(overlay_));
106 }
107
108 void AVDAOverlayHelperImpl::OnOverlayFailed(AndroidOverlay* overlay) {
109 // We shouldn't get a failure for any overlay except the incoming one.
110 DCHECK_EQ(overlay, overlay_.get());
111
112 // If we owe the client a notification callback, then send it.
113 if (client_notification_pending_) {
114 // The overlay that we requested failed, so notify the client to try
115 // using SurfaceTexture instead.
116 client_notification_pending_ = false;
117 use_surface_texture_cb_.Run();
118 }
119
120 overlay_ = nullptr;
121 }
122
123 void AVDAOverlayHelperImpl::OnSurfaceDestroyed(AndroidOverlay* overlay) {
124 // We shouldn't get OnSurfaceDestroyed unless we previously got Ready. In
125 // that case, we should have notified the client then.
126 DCHECK(!client_notification_pending_);
127
128 // We should not get OnSurfaceDestroyed for the incoming overlay, since we
129 // should't get OnSurfaceDestroyed before OnSurfaceReady. OnSurfaceReady
130 // should imply that this isn't the incoming overlay.
131 DCHECK_NE(overlay_.get(), overlay);
132
133 // We unconditionally send 'stop immediately', since we don't know what
134 // overlay this is. Even if we revoked the overlay before, we may have done
135 // so with the slow transition, which isn't good enough now. The client has
136 // to be smart enoug to understand if it's currently using |overlay| or not.
137
138 // Also remember that we don't know when the client drops the overlay, after
139 // we revoke it. We can get callbacks until that happens, even if (for
140 // example), the overlay is waiting for MediaCodec destruction. So, it's
141 // likely that we'll send callbacks for overlays that the client is already
142 // not using.
143 stop_immediately_cb_.Run(overlay);
144 }
145
146 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698