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

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

Issue 1639963002: AndroidVideoDecodeAccelerator can now render to a SurfaceView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase only Created 4 years, 10 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
« no previous file with comments | « content/common/gpu/media/avda_codec_image.h ('k') | media/video/video_decode_accelerator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "content/common/gpu/media/avda_codec_image.h" 5 #include "content/common/gpu/media/avda_codec_image.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "content/common/gpu/media/avda_shared_state.h" 10 #include "content/common/gpu/media/avda_shared_state.h"
11 #include "gpu/command_buffer/service/context_group.h" 11 #include "gpu/command_buffer/service/context_group.h"
12 #include "gpu/command_buffer/service/context_state.h" 12 #include "gpu/command_buffer/service/context_state.h"
13 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 13 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
14 #include "gpu/command_buffer/service/texture_manager.h" 14 #include "gpu/command_buffer/service/texture_manager.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 content { 19 namespace content {
20 20
21 AVDACodecImage::AVDACodecImage( 21 AVDACodecImage::AVDACodecImage(
22 const scoped_refptr<AVDASharedState>& shared_state, 22 const scoped_refptr<AVDASharedState>& shared_state,
23 media::VideoCodecBridge* codec, 23 media::VideoCodecBridge* codec,
24 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder, 24 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder,
25 const scoped_refptr<gfx::SurfaceTexture>& surface_texture) 25 const scoped_refptr<gfx::SurfaceTexture>& surface_texture)
26 : shared_state_(shared_state), 26 : shared_state_(shared_state),
27 codec_buffer_index_(-1), 27 codec_buffer_index_(kInvalidCodecBufferIndex),
28 media_codec_(codec), 28 media_codec_(codec),
29 decoder_(decoder), 29 decoder_(decoder),
30 surface_texture_(surface_texture), 30 surface_texture_(surface_texture),
31 detach_surface_texture_on_destruction_(false), 31 detach_surface_texture_on_destruction_(false),
32 texture_(0), 32 texture_(0),
33 need_shader_info_(true), 33 need_shader_info_(true),
34 texmatrix_uniform_location_(-1) { 34 texmatrix_uniform_location_(-1) {
35 memset(gl_matrix_, 0, sizeof(gl_matrix_)); 35 memset(gl_matrix_, 0, sizeof(gl_matrix_));
36 gl_matrix_[0] = gl_matrix_[5] = gl_matrix_[10] = gl_matrix_[15] = 1.0f; 36 gl_matrix_[0] = gl_matrix_[5] = gl_matrix_[10] = gl_matrix_[15] = 1.0f;
37 } 37 }
(...skipping 10 matching lines...) Expand all
48 return GL_RGBA; 48 return GL_RGBA;
49 } 49 }
50 50
51 bool AVDACodecImage::BindTexImage(unsigned target) { 51 bool AVDACodecImage::BindTexImage(unsigned target) {
52 return false; 52 return false;
53 } 53 }
54 54
55 void AVDACodecImage::ReleaseTexImage(unsigned target) {} 55 void AVDACodecImage::ReleaseTexImage(unsigned target) {}
56 56
57 bool AVDACodecImage::CopyTexImage(unsigned target) { 57 bool AVDACodecImage::CopyTexImage(unsigned target) {
58 if (!surface_texture_)
59 return false;
60
58 if (target != GL_TEXTURE_EXTERNAL_OES) 61 if (target != GL_TEXTURE_EXTERNAL_OES)
59 return false; 62 return false;
60 63
61 // Verify that the currently bound texture is the right one. If we're not 64 // Verify that the currently bound texture is the right one. If we're not
62 // copying to a Texture that shares our service_id, then we can't do much. 65 // copying to a Texture that shares our service_id, then we can't do much.
63 // This will force a copy. 66 // This will force a copy.
64 // TODO(liberato): Fall back to a copy that uses the texture matrix. 67 // TODO(liberato): Fall back to a copy that uses the texture matrix.
65 GLint bound_service_id = 0; 68 GLint bound_service_id = 0;
66 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); 69 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
67 if (bound_service_id != shared_state_->surface_texture_service_id()) 70 if (bound_service_id != shared_state_->surface_texture_service_id())
(...skipping 27 matching lines...) Expand all
95 const gfx::Point& offset, 98 const gfx::Point& offset,
96 const gfx::Rect& rect) { 99 const gfx::Rect& rect) {
97 return false; 100 return false;
98 } 101 }
99 102
100 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 103 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
101 int z_order, 104 int z_order,
102 gfx::OverlayTransform transform, 105 gfx::OverlayTransform transform,
103 const gfx::Rect& bounds_rect, 106 const gfx::Rect& bounds_rect,
104 const gfx::RectF& crop_rect) { 107 const gfx::RectF& crop_rect) {
105 return false; 108 // This should only be called when we're rendering to a SurfaceView.
109 if (surface_texture_) {
110 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is "
111 "SurfaceTexture backed.";
112 return false;
113 }
114
115 if (codec_buffer_index_ != kInvalidCodecBufferIndex) {
116 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
117 codec_buffer_index_ = kInvalidCodecBufferIndex;
118 }
119 return true;
106 } 120 }
107 121
108 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, 122 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
109 uint64_t process_tracing_id, 123 uint64_t process_tracing_id,
110 const std::string& dump_name) {} 124 const std::string& dump_name) {}
111 125
112 void AVDACodecImage::UpdateSurfaceTexture() { 126 void AVDACodecImage::UpdateSurfaceTexture() {
127 DCHECK(surface_texture_);
128
113 // Render via the media codec if needed. 129 // Render via the media codec if needed.
114 if (codec_buffer_index_ <= -1 || !media_codec_) 130 if (codec_buffer_index_ == kInvalidCodecBufferIndex || !media_codec_)
115 return; 131 return;
116 132
117 // The decoder buffer is still pending. 133 // The decoder buffer is still pending.
118 // This must be synchronous, so wait for OnFrameAvailable. 134 // This must be synchronous, so wait for OnFrameAvailable.
119 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true); 135 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
120 { 136 {
121 SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame"); 137 SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame");
122 shared_state_->WaitForFrameAvailable(); 138 shared_state_->WaitForFrameAvailable();
123 } 139 }
124 140
125 // Don't bother to check if we're rendered again. 141 // Don't bother to check if we're rendered again.
126 codec_buffer_index_ = -1; 142 codec_buffer_index_ = kInvalidCodecBufferIndex;
127 143
128 // Swap the rendered image to the front. 144 // Swap the rendered image to the front.
129 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; 145 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
130 if (!shared_state_->context()->IsCurrent(NULL)) { 146 if (!shared_state_->context()->IsCurrent(NULL)) {
131 scoped_make_current.reset(new ui::ScopedMakeCurrent( 147 scoped_make_current.reset(new ui::ScopedMakeCurrent(
132 shared_state_->context(), shared_state_->surface())); 148 shared_state_->context(), shared_state_->surface()));
133 } 149 }
134 surface_texture_->UpdateTexImage(); 150 surface_texture_->UpdateTexImage();
135 151
136 // Helpfully, this is already column major. 152 // Helpfully, this is already column major.
137 surface_texture_->GetTransformMatrix(gl_matrix_); 153 surface_texture_->GetTransformMatrix(gl_matrix_);
138 } 154 }
139 155
140 void AVDACodecImage::SetMediaCodecBufferIndex(int buffer_index) { 156 void AVDACodecImage::SetMediaCodecBufferIndex(int buffer_index) {
141 codec_buffer_index_ = buffer_index; 157 codec_buffer_index_ = buffer_index;
142 } 158 }
143 159
144 int AVDACodecImage::GetMediaCodecBufferIndex() const { 160 int AVDACodecImage::GetMediaCodecBufferIndex() const {
145 return codec_buffer_index_; 161 return codec_buffer_index_;
146 } 162 }
147 163
148 void AVDACodecImage::SetSize(const gfx::Size& size) { 164 void AVDACodecImage::SetSize(const gfx::Size& size) {
149 size_ = size; 165 size_ = size;
150 } 166 }
151 167
152 void AVDACodecImage::SetMediaCodec(media::MediaCodecBridge* codec) { 168 void AVDACodecImage::SetMediaCodec(media::MediaCodecBridge* codec) {
153 media_codec_ = codec; 169 media_codec_ = codec;
154 } 170 }
155 171
156 void AVDACodecImage::setTexture(gpu::gles2::Texture* texture) { 172 void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) {
157 texture_ = texture; 173 texture_ = texture;
158 } 174 }
159 175
160 void AVDACodecImage::AttachSurfaceTextureToContext() { 176 void AVDACodecImage::AttachSurfaceTextureToContext() {
177 DCHECK(surface_texture_);
178
161 // Attach the surface texture to the first context we're bound on, so that 179 // Attach the surface texture to the first context we're bound on, so that
162 // no context switch is needed later. 180 // no context switch is needed later.
163
164 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 181 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
165 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 182 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
166 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 183 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
167 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 184 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
168 185
169 // The surface texture is already detached, so just attach it. 186 // The surface texture is already detached, so just attach it.
170 // We could do this earlier, but SurfaceTexture has context affinity, and we 187 // We could do this earlier, but SurfaceTexture has context affinity, and we
171 // don't want to require a context switch. 188 // don't want to require a context switch.
172 surface_texture_->AttachToGLContext(); 189 surface_texture_->AttachToGLContext();
173 shared_state_->did_attach_surface_texture(); 190 shared_state_->did_attach_surface_texture();
174 } 191 }
175 192
176 void AVDACodecImage::InstallTextureMatrix() { 193 void AVDACodecImage::InstallTextureMatrix() {
194 DCHECK(surface_texture_);
195
177 // glUseProgram() has been run already -- just modify the uniform. 196 // glUseProgram() has been run already -- just modify the uniform.
178 // Updating this via VideoFrameProvider::Client::DidUpdateMatrix() would 197 // Updating this via VideoFrameProvider::Client::DidUpdateMatrix() would
179 // be a better solution, except that we'd definitely miss a frame at this 198 // be a better solution, except that we'd definitely miss a frame at this
180 // point in drawing. 199 // point in drawing.
181 // Our current method assumes that we'll end up being a stream resource, 200 // Our current method assumes that we'll end up being a stream resource,
182 // and that the program has a texMatrix uniform that does what we want. 201 // and that the program has a texMatrix uniform that does what we want.
183 if (need_shader_info_) { 202 if (need_shader_info_) {
184 GLint program_id = -1; 203 GLint program_id = -1;
185 glGetIntegerv(GL_CURRENT_PROGRAM, &program_id); 204 glGetIntegerv(GL_CURRENT_PROGRAM, &program_id);
186 205
187 if (program_id >= 0) { 206 if (program_id >= 0) {
188 // This is memorized from cc/output/shader.cc . 207 // This is memorized from cc/output/shader.cc .
189 const char* uniformName = "texMatrix"; 208 const char* uniformName = "texMatrix";
190 texmatrix_uniform_location_ = 209 texmatrix_uniform_location_ =
191 glGetUniformLocation(program_id, uniformName); 210 glGetUniformLocation(program_id, uniformName);
192 DCHECK(texmatrix_uniform_location_ != -1); 211 DCHECK(texmatrix_uniform_location_ != -1);
193 } 212 }
194 213
195 // Only try once. 214 // Only try once.
196 need_shader_info_ = false; 215 need_shader_info_ = false;
197 } 216 }
198 217
199 if (texmatrix_uniform_location_ >= 0) { 218 if (texmatrix_uniform_location_ >= 0) {
200 glUniformMatrix4fv(texmatrix_uniform_location_, 1, false, gl_matrix_); 219 glUniformMatrix4fv(texmatrix_uniform_location_, 1, false, gl_matrix_);
201 } 220 }
202 } 221 }
203 222
204 } // namespace content 223 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/avda_codec_image.h ('k') | media/video/video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698