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

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

Issue 2461073002: Use MediaCodec.setOutputSurface() for fullscreen transitions on M. (Closed)
Patch Set: Fix IPC, but now everything explodes :( Created 4 years, 1 month 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/avda_codec_image.h" 5 #include "media/gpu/avda_codec_image.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/texture_manager.h" 12 #include "gpu/command_buffer/service/texture_manager.h"
13 #include "media/base/android/sdk_media_codec_bridge.h" 13 #include "media/base/android/sdk_media_codec_bridge.h"
14 #include "media/gpu/avda_shared_state.h" 14 #include "media/gpu/avda_shared_state.h"
15 #include "ui/gl/android/surface_texture.h" 15 #include "ui/gl/android/surface_texture.h"
16 #include "ui/gl/gl_context.h" 16 #include "ui/gl/gl_context.h"
17 #include "ui/gl/scoped_make_current.h" 17 #include "ui/gl/scoped_make_current.h"
18 18
19 namespace media { 19 namespace media {
20 20
21 AVDACodecImage::AVDACodecImage( 21 AVDACodecImage::AVDACodecImage(
22 int picture_buffer_id, 22 int picture_buffer_id,
23 const scoped_refptr<AVDASharedState>& shared_state, 23 const scoped_refptr<AVDASharedState>& shared_state,
24 VideoCodecBridge* codec, 24 VideoCodecBridge* codec,
25 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder) 25 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder)
26 : shared_state_(shared_state), 26 : shared_state_(shared_state),
27 codec_buffer_index_(kInvalidCodecBufferIndex), 27 codec_buffer_index_(kInvalidCodecBufferIndex),
28 media_codec_(codec), 28 media_codec_(codec),
29 decoder_(decoder), 29 decoder_(decoder),
30 has_surface_texture_(!!shared_state_->surface_texture_service_id()),
31 texture_(0), 30 texture_(0),
32 picture_buffer_id_(picture_buffer_id) { 31 picture_buffer_id_(picture_buffer_id) {
33 shared_state_->SetImageForPicture(picture_buffer_id_, this); 32 shared_state_->SetImageForPicture(picture_buffer_id_, this);
34 } 33 }
35 34
36 AVDACodecImage::~AVDACodecImage() { 35 AVDACodecImage::~AVDACodecImage() {
37 shared_state_->SetImageForPicture(picture_buffer_id_, nullptr); 36 shared_state_->SetImageForPicture(picture_buffer_id_, nullptr);
38 } 37 }
39 38
40 void AVDACodecImage::Destroy(bool have_context) {} 39 void AVDACodecImage::Destroy(bool have_context) {}
41 40
42 gfx::Size AVDACodecImage::GetSize() { 41 gfx::Size AVDACodecImage::GetSize() {
43 return size_; 42 return size_;
44 } 43 }
45 44
46 unsigned AVDACodecImage::GetInternalFormat() { 45 unsigned AVDACodecImage::GetInternalFormat() {
47 return GL_RGBA; 46 return GL_RGBA;
48 } 47 }
49 48
50 bool AVDACodecImage::BindTexImage(unsigned target) { 49 bool AVDACodecImage::BindTexImage(unsigned target) {
51 return false; 50 return false;
52 } 51 }
53 52
54 void AVDACodecImage::ReleaseTexImage(unsigned target) {} 53 void AVDACodecImage::ReleaseTexImage(unsigned target) {}
55 54
56 bool AVDACodecImage::CopyTexImage(unsigned target) { 55 bool AVDACodecImage::CopyTexImage(unsigned target) {
57 if (!has_surface_texture_) 56 if (!shared_state_->surface_texture_service_id())
58 return false; 57 return false;
59 58
60 if (target != GL_TEXTURE_EXTERNAL_OES) 59 if (target != GL_TEXTURE_EXTERNAL_OES)
61 return false; 60 return false;
62 61
63 GLint bound_service_id = 0; 62 GLint bound_service_id = 0;
64 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); 63 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
65 // We insist that the currently bound texture is the right one. 64 // We insist that the currently bound texture is the right one.
66 if (bound_service_id != 65 if (bound_service_id !=
67 static_cast<GLint>(shared_state_->surface_texture_service_id())) { 66 static_cast<GLint>(shared_state_->surface_texture_service_id())) {
(...skipping 21 matching lines...) Expand all
89 const gfx::Rect& rect) { 88 const gfx::Rect& rect) {
90 return false; 89 return false;
91 } 90 }
92 91
93 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 92 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
94 int z_order, 93 int z_order,
95 gfx::OverlayTransform transform, 94 gfx::OverlayTransform transform,
96 const gfx::Rect& bounds_rect, 95 const gfx::Rect& bounds_rect,
97 const gfx::RectF& crop_rect) { 96 const gfx::RectF& crop_rect) {
98 // This should only be called when we're rendering to a SurfaceView. 97 // This should only be called when we're rendering to a SurfaceView.
99 if (has_surface_texture_) { 98 if (shared_state_->surface_texture_service_id()) {
100 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is " 99 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is "
101 "SurfaceTexture backed."; 100 "SurfaceTexture backed.";
102 return false; 101 return false;
103 } 102 }
104 103
105 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER); 104 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
106 return true; 105 return true;
107 } 106 }
108 107
109 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, 108 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
110 uint64_t process_tracing_id, 109 uint64_t process_tracing_id,
111 const std::string& dump_name) {} 110 const std::string& dump_name) {}
112 111
113 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) { 112 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
114 DCHECK(has_surface_texture_); 113 DCHECK(shared_state_->surface_texture_service_id());
115 DCHECK_EQ(codec_buffer_index_, kUpdateOnly); 114 DCHECK_EQ(codec_buffer_index_, kUpdateOnly);
116 codec_buffer_index_ = kRendered; 115 codec_buffer_index_ = kRendered;
117 116
118 // Swap the rendered image to the front. 117 // Swap the rendered image to the front.
119 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current = 118 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current =
120 MakeCurrentIfNeeded(); 119 MakeCurrentIfNeeded();
121 120
122 // If we changed contexts, then we always want to restore it, since the caller 121 // If we changed contexts, then we always want to restore it, since the caller
123 // doesn't know that we're switching contexts. 122 // doesn't know that we're switching contexts.
124 if (scoped_make_current) 123 if (scoped_make_current)
(...skipping 20 matching lines...) Expand all
145 144
146 void AVDACodecImage::UpdateSurfaceInternal( 145 void AVDACodecImage::UpdateSurfaceInternal(
147 UpdateMode update_mode, 146 UpdateMode update_mode,
148 RestoreBindingsMode attached_bindings_mode) { 147 RestoreBindingsMode attached_bindings_mode) {
149 if (!IsCodecBufferOutstanding()) 148 if (!IsCodecBufferOutstanding())
150 return; 149 return;
151 150
152 ReleaseOutputBuffer(update_mode); 151 ReleaseOutputBuffer(update_mode);
153 152
154 // SurfaceViews are updated implicitly, so no further steps are necessary. 153 // SurfaceViews are updated implicitly, so no further steps are necessary.
155 if (!has_surface_texture_) { 154 if (!shared_state_->surface_texture_service_id()) {
156 DCHECK(update_mode != UpdateMode::RENDER_TO_BACK_BUFFER); 155 DCHECK(update_mode != UpdateMode::RENDER_TO_BACK_BUFFER);
157 return; 156 return;
158 } 157 }
159 158
160 // If front buffer rendering hasn't been requested, exit early. 159 // If front buffer rendering hasn't been requested, exit early.
161 if (update_mode != UpdateMode::RENDER_TO_FRONT_BUFFER) 160 if (update_mode != UpdateMode::RENDER_TO_FRONT_BUFFER)
162 return; 161 return;
163 162
164 UpdateSurfaceTexture(attached_bindings_mode); 163 UpdateSurfaceTexture(attached_bindings_mode);
165 } 164 }
166 165
167 void AVDACodecImage::ReleaseOutputBuffer(UpdateMode update_mode) { 166 void AVDACodecImage::ReleaseOutputBuffer(UpdateMode update_mode) {
168 DCHECK(IsCodecBufferOutstanding()); 167 DCHECK(IsCodecBufferOutstanding());
169 168
170 // In case of discard, simply discard and clear our codec buffer index. 169 // In case of discard, simply discard and clear our codec buffer index.
171 if (update_mode == UpdateMode::DISCARD_CODEC_BUFFER) { 170 if (update_mode == UpdateMode::DISCARD_CODEC_BUFFER) {
172 if (codec_buffer_index_ != kUpdateOnly) 171 if (codec_buffer_index_ != kUpdateOnly)
173 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false); 172 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false);
174 173
175 // Note: No need to wait for the frame to be available in the kUpdateOnly 174 // Note: No need to wait for the frame to be available in the kUpdateOnly
176 // case since it will be or has been waited on by another release call. 175 // case since it will be or has been waited on by another release call.
177 codec_buffer_index_ = kInvalidCodecBufferIndex; 176 codec_buffer_index_ = kInvalidCodecBufferIndex;
178 return; 177 return;
179 } 178 }
180 179
181 DCHECK(update_mode == UpdateMode::RENDER_TO_BACK_BUFFER || 180 DCHECK(update_mode == UpdateMode::RENDER_TO_BACK_BUFFER ||
182 update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER); 181 update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER);
183 182
184 if (!has_surface_texture_) { 183 if (!shared_state_->surface_texture_service_id()) {
185 DCHECK(update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER); 184 DCHECK(update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER);
186 DCHECK_GE(codec_buffer_index_, 0); 185 DCHECK_GE(codec_buffer_index_, 0);
187 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true); 186 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
188 codec_buffer_index_ = kRendered; 187 codec_buffer_index_ = kRendered;
189 return; 188 return;
190 } 189 }
191 190
192 // If we've already released to the back buffer, there's nothing left to do, 191 // If we've already released to the back buffer, there's nothing left to do,
193 // but wait for the previously released buffer if necessary. 192 // but wait for the previously released buffer if necessary.
194 if (codec_buffer_index_ != kUpdateOnly) { 193 if (codec_buffer_index_ != kUpdateOnly) {
195 DCHECK(has_surface_texture_); 194 DCHECK(shared_state_->surface_texture_service_id());
196 DCHECK_GE(codec_buffer_index_, 0); 195 DCHECK_GE(codec_buffer_index_, 0);
197 shared_state_->RenderCodecBufferToSurfaceTexture(media_codec_, 196 shared_state_->RenderCodecBufferToSurfaceTexture(media_codec_,
198 codec_buffer_index_); 197 codec_buffer_index_);
199 codec_buffer_index_ = kUpdateOnly; 198 codec_buffer_index_ = kUpdateOnly;
200 } 199 }
201 200
202 // Only wait for the SurfaceTexture update if we're rendering to the front. 201 // Only wait for the SurfaceTexture update if we're rendering to the front.
203 if (update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER) 202 if (update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER)
204 shared_state_->WaitForFrameAvailable(); 203 shared_state_->WaitForFrameAvailable();
205 } 204 }
206 205
207 std::unique_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() { 206 std::unique_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() {
208 DCHECK(shared_state_->context()); 207 DCHECK(shared_state_->context());
209 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current; 208 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current;
210 // Remember: virtual contexts return true if and only if their shared context 209 // Remember: virtual contexts return true if and only if their shared context
211 // is current, regardless of which virtual context it is. 210 // is current, regardless of which virtual context it is.
212 if (!shared_state_->context()->IsCurrent(NULL)) { 211 if (!shared_state_->context()->IsCurrent(NULL)) {
213 scoped_make_current.reset(new ui::ScopedMakeCurrent( 212 scoped_make_current.reset(new ui::ScopedMakeCurrent(
214 shared_state_->context(), shared_state_->surface())); 213 shared_state_->context(), shared_state_->surface()));
215 } 214 }
216 215
217 return scoped_make_current; 216 return scoped_make_current;
218 } 217 }
219 218
220 void AVDACodecImage::GetTextureMatrix(float matrix[16]) { 219 void AVDACodecImage::GetTextureMatrix(float matrix[16]) {
221 // Our current matrix may be stale. Update it if possible. 220 // Our current matrix may be stale. Update it if possible.
222 if (has_surface_texture_) 221 if (shared_state_->surface_texture_service_id())
223 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER); 222 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
224 shared_state_->GetTransformMatrix(matrix); 223 shared_state_->GetTransformMatrix(matrix);
225 YInvertMatrix(matrix); 224 YInvertMatrix(matrix);
226 } 225 }
227 226
228 bool AVDACodecImage::IsCodecBufferOutstanding() const { 227 bool AVDACodecImage::IsCodecBufferOutstanding() const {
229 static_assert(kUpdateOnly < 0 && kUpdateOnly > kRendered && 228 static_assert(kUpdateOnly < 0 && kUpdateOnly > kRendered &&
230 kRendered > kInvalidCodecBufferIndex, 229 kRendered > kInvalidCodecBufferIndex,
231 "Codec buffer index enum values are not ordered correctly."); 230 "Codec buffer index enum values are not ordered correctly.");
232 return codec_buffer_index_ > kRendered && media_codec_; 231 return codec_buffer_index_ > kRendered && media_codec_;
233 } 232 }
234 233
235 } // namespace media 234 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698