| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |