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

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

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Squash and rebase Created 4 years, 7 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 2015 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 "content/common/gpu/media/android_copying_backing_strategy.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h"
10 #include "content/common/gpu/media/avda_return_on_failure.h"
11 #include "gpu/command_buffer/service/context_group.h"
12 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
13 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
14 #include "media/base/limits.h"
15 #include "media/video/picture.h"
16 #include "ui/gl/android/surface_texture.h"
17 #include "ui/gl/gl_bindings.h"
18
19 namespace content {
20
21 AndroidCopyingBackingStrategy::AndroidCopyingBackingStrategy(
22 AVDAStateProvider* state_provider)
23 : state_provider_(state_provider),
24 surface_texture_id_(0),
25 media_codec_(nullptr) {}
26
27 AndroidCopyingBackingStrategy::~AndroidCopyingBackingStrategy() {}
28
29 gfx::ScopedJavaSurface AndroidCopyingBackingStrategy::Initialize(
30 int surface_view_id) {
31 if (surface_view_id != media::VideoDecodeAccelerator::Config::kNoSurfaceID) {
32 LOG(ERROR) << "The copying strategy should not be initialized with a "
33 "surface id.";
34 return gfx::ScopedJavaSurface();
35 }
36
37 // Create a texture and attach the SurfaceTexture to it.
38 glGenTextures(1, &surface_texture_id_);
39 glActiveTexture(GL_TEXTURE0);
40 glBindTexture(GL_TEXTURE_EXTERNAL_OES, surface_texture_id_);
41
42 // Note that the target will be correctly sized, so nearest filtering is all
43 // that's needed.
44 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
45 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
46 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
47 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
48
49 state_provider_->GetGlDecoder()->RestoreTextureUnitBindings(0);
50 state_provider_->GetGlDecoder()->RestoreActiveTexture();
51
52 surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_);
53
54 return gfx::ScopedJavaSurface(surface_texture_.get());
55 }
56
57 void AndroidCopyingBackingStrategy::Cleanup(
58 bool have_context,
59 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
60 DCHECK(state_provider_->ThreadChecker().CalledOnValidThread());
61
62 if (copier_)
63 copier_->Destroy();
64
65 if (surface_texture_id_ && have_context)
66 glDeleteTextures(1, &surface_texture_id_);
67 }
68
69 scoped_refptr<gfx::SurfaceTexture>
70 AndroidCopyingBackingStrategy::GetSurfaceTexture() const {
71 return surface_texture_;
72 }
73
74 uint32_t AndroidCopyingBackingStrategy::GetTextureTarget() const {
75 return GL_TEXTURE_2D;
76 }
77
78 gfx::Size AndroidCopyingBackingStrategy::GetPictureBufferSize() const {
79 return state_provider_->GetSize();
80 }
81
82 void AndroidCopyingBackingStrategy::UseCodecBufferForPictureBuffer(
83 int32_t codec_buf_index,
84 const media::PictureBuffer& picture_buffer) {
85 // Make sure that the decoder is available.
86 RETURN_ON_FAILURE(state_provider_, state_provider_->GetGlDecoder().get(),
87 "Failed to get gles2 decoder instance.", ILLEGAL_STATE);
88
89 // Render the codec buffer into |surface_texture_|, and switch it to be
90 // the front buffer.
91 // This ignores the emitted ByteBuffer and instead relies on rendering to
92 // the codec's SurfaceTexture and then copying from that texture to the
93 // client's PictureBuffer's texture. This means that each picture's data
94 // is written three times: once to the ByteBuffer, once to the
95 // SurfaceTexture, and once to the client's texture. It would be nicer to
96 // either:
97 // 1) Render directly to the client's texture from MediaCodec (one write);
98 // or
99 // 2) Upload the ByteBuffer to the client's texture (two writes).
100 // Unfortunately neither is possible:
101 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture
102 // written to can't change during the codec's lifetime. b/11990461
103 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific,
104 // opaque/non-standard format. It's not possible to negotiate the
105 // decoder to emit a specific colorspace, even using HW CSC. b/10706245
106 // So, we live with these two extra copies per picture :(
107 {
108 TRACE_EVENT0("media", "AVDA::ReleaseOutputBuffer");
109 media_codec_->ReleaseOutputBuffer(codec_buf_index, true);
110 }
111
112 {
113 TRACE_EVENT0("media", "AVDA::UpdateTexImage");
114 surface_texture_->UpdateTexImage();
115 }
116
117 float transform_matrix[16];
118 surface_texture_->GetTransformMatrix(transform_matrix);
119
120 DCHECK_LE(1u, picture_buffer.texture_ids().size());
121 uint32_t picture_buffer_texture_id = picture_buffer.texture_ids()[0];
122
123 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
124 // needed because it takes 10s of milliseconds to initialize.
125 if (!copier_) {
126 copier_.reset(new gpu::CopyTextureCHROMIUMResourceManager());
127 copier_->Initialize(state_provider_->GetGlDecoder().get(),
128 state_provider_->GetGlDecoder()->GetContextGroup()->
129 feature_info()->feature_flags());
130 }
131
132 // Here, we copy |surface_texture_id_| to the picture buffer instead of
133 // setting new texture to |surface_texture_| by calling attachToGLContext()
134 // because:
135 // 1. Once we call detachFrameGLContext(), it deletes the texture previously
136 // attached.
137 // 2. SurfaceTexture requires us to apply a transform matrix when we show
138 // the texture.
139 copier_->DoCopyTextureWithTransform(
140 state_provider_->GetGlDecoder().get(), GL_TEXTURE_EXTERNAL_OES,
141 surface_texture_id_, GL_TEXTURE_2D, picture_buffer_texture_id,
142 state_provider_->GetSize().width(), state_provider_->GetSize().height(),
143 true, false, false, transform_matrix);
144 }
145
146 void AndroidCopyingBackingStrategy::CodecChanged(
147 media::VideoCodecBridge* codec) {
148 media_codec_ = codec;
149 }
150
151 void AndroidCopyingBackingStrategy::OnFrameAvailable() {
152 // TODO(liberato): crbug.com/574948 . The OnFrameAvailable logic can be
153 // moved into AVDA, and we should wait for it before doing the copy.
154 // Because there were some test failures, we don't do this now but
155 // instead preserve the old behavior.
156 }
157
158 bool AndroidCopyingBackingStrategy::ArePicturesOverlayable() {
159 return false;
160 }
161
162 void AndroidCopyingBackingStrategy::UpdatePictureBufferSize(
163 media::PictureBuffer* picture_buffer,
164 const gfx::Size& new_size) {
165 // This strategy uses 2D textures who's allocated memory is dependent on the
166 // size. To update size in all places, we must:
167 // 1) Update the PictureBuffer meta-data
168 picture_buffer->set_size(new_size);
169
170 // 2) Update the GL texture via glTexImage2D. This step assumes the caller
171 // has made our GL context current.
172 DCHECK_LE(1u, picture_buffer->texture_ids().size());
173 glBindTexture(GL_TEXTURE_2D, picture_buffer->texture_ids()[0]);
174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, new_size.width(), new_size.height(),
175 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
176 state_provider_->GetGlDecoder()->RestoreActiveTextureUnitBinding(
177 GL_TEXTURE_2D);
178
179 // 3) Update the CHROMIUM Texture's size.
180 gpu::gles2::TextureRef* texture_ref =
181 state_provider_->GetTextureForPicture(*picture_buffer);
182 RETURN_IF_NULL(texture_ref);
183 gpu::gles2::TextureManager* texture_manager =
184 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
185 RETURN_IF_NULL(texture_manager);
186 texture_manager->SetLevelInfo(texture_ref, GetTextureTarget(), 0, GL_RGBA,
187 new_size.width(), new_size.height(), 1, 0,
188 GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(new_size));
189 }
190
191 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698