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

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

Issue 2461073002: Use MediaCodec.setOutputSurface() for fullscreen transitions on M. (Closed)
Patch Set: Simplify APIs. 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_shared_state.h" 5 #include "media/gpu/avda_shared_state.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "media/gpu/avda_codec_image.h" 9 #include "media/gpu/avda_codec_image.h"
10 #include "ui/gl/android/surface_texture.h" 10 #include "ui/gl/android/surface_texture.h"
11 #include "ui/gl/gl_bindings.h" 11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/scoped_make_current.h" 12 #include "ui/gl/scoped_make_current.h"
13 13
14 namespace media { 14 namespace media {
15 15
16 // Handle OnFrameAvailable callbacks safely. Since they occur asynchronously,
17 // we take care that the object that wants them still exists. WeakPtrs cannot
18 // be used because OnFrameAvailable callbacks can occur on any thread. We also
19 // can't guarantee when the SurfaceTexture will quit sending callbacks to
20 // coordinate with the destruction of the AVDA and PictureBufferManager, so we
21 // have a separate object that the callback can own.
22 class AVDASharedState::OnFrameAvailableHandler
23 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> {
24 public:
25 // We do not retain ownership of |listener|. It must remain valid until after
26 // ClearListener() is called. This will register with |surface_texture| to
27 // receive OnFrameAvailable callbacks.
28 OnFrameAvailableHandler(AVDASharedState* listener,
29 gl::SurfaceTexture* surface_texture)
30 : listener_(listener) {
31 surface_texture->SetFrameAvailableCallbackOnAnyThread(
32 base::Bind(&OnFrameAvailableHandler::OnFrameAvailable,
33 scoped_refptr<OnFrameAvailableHandler>(this)));
34 }
35
36 // Forget about |listener_|, which is required before one deletes it.
37 // No further callbacks will happen once this completes.
38 void ClearListener() {
39 base::AutoLock lock(lock_);
40 listener_ = nullptr;
41 }
42
43 // Notify the listener if there is one.
44 void OnFrameAvailable() {
45 base::AutoLock auto_lock(lock_);
46 if (listener_)
47 listener_->SignalFrameAvailable();
48 }
49
50 private:
51 friend class base::RefCountedThreadSafe<OnFrameAvailableHandler>;
52
53 ~OnFrameAvailableHandler() { DCHECK(!listener_); }
54
55 // Protects changes to listener_.
56 base::Lock lock_;
57
58 // The AVDASharedState that wants the OnFrameAvailable callback.
59 AVDASharedState* listener_;
60
61 DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
62 };
63
16 AVDASharedState::AVDASharedState() 64 AVDASharedState::AVDASharedState()
17 : surface_texture_service_id_(0), 65 : surface_texture_service_id_(0),
18 frame_available_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, 66 frame_available_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
19 base::WaitableEvent::InitialState::NOT_SIGNALED), 67 base::WaitableEvent::InitialState::NOT_SIGNALED),
20 68
21 gl_matrix_{ 69 gl_matrix_{
22 1, 0, 0, 0, // Default to a sane guess just in case we can't get the 70 1, 0, 0, 0, // Default to a sane guess just in case we can't get the
23 0, 1, 0, 0, // matrix on the first call. Will be Y-flipped later. 71 0, 1, 0, 0, // matrix on the first call. Will be Y-flipped later.
24 0, 0, 1, 0, // 72 0, 0, 1, 0, //
25 0, 0, 0, 1, // Comment preserves 4x4 formatting. 73 0, 0, 0, 1, // Comment preserves 4x4 formatting.
26 } {} 74 } {}
27 75
28 AVDASharedState::~AVDASharedState() { 76 AVDASharedState::~AVDASharedState() {
29 if (!surface_texture_service_id_) 77 if (!surface_texture_service_id_)
30 return; 78 return;
31 79
80 on_frame_available_handler_->ClearListener();
32 ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get()); 81 ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get());
33 if (scoped_make_current.Succeeded()) { 82 if (scoped_make_current.Succeeded()) {
34 glDeleteTextures(1, &surface_texture_service_id_); 83 glDeleteTextures(1, &surface_texture_service_id_);
35 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 84 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
36 } 85 }
37 } 86 }
38 87
39 void AVDASharedState::SignalFrameAvailable() { 88 void AVDASharedState::SignalFrameAvailable() {
40 frame_available_event_.Signal(); 89 frame_available_event_.Signal();
41 } 90 }
(...skipping 24 matching lines...) Expand all
66 << elapsed.InMillisecondsF() 115 << elapsed.InMillisecondsF()
67 << "ms, additionally waited: " << remaining.InMillisecondsF() 116 << "ms, additionally waited: " << remaining.InMillisecondsF()
68 << "ms, total: " << (elapsed + remaining).InMillisecondsF() 117 << "ms, total: " << (elapsed + remaining).InMillisecondsF()
69 << "ms"; 118 << "ms";
70 } 119 }
71 } 120 }
72 121
73 void AVDASharedState::SetSurfaceTexture( 122 void AVDASharedState::SetSurfaceTexture(
74 scoped_refptr<gl::SurfaceTexture> surface_texture, 123 scoped_refptr<gl::SurfaceTexture> surface_texture,
75 GLuint attached_service_id) { 124 GLuint attached_service_id) {
125 DCHECK(surface_texture);
126 DCHECK(attached_service_id);
76 surface_texture_ = surface_texture; 127 surface_texture_ = surface_texture;
77 surface_texture_service_id_ = attached_service_id; 128 surface_texture_service_id_ = attached_service_id;
78 context_ = gl::GLContext::GetCurrent(); 129 context_ = gl::GLContext::GetCurrent();
79 surface_ = gl::GLSurface::GetCurrent(); 130 surface_ = gl::GLSurface::GetCurrent();
80 DCHECK(context_); 131 on_frame_available_handler_ =
81 DCHECK(surface_); 132 new OnFrameAvailableHandler(this, surface_texture_.get());
82 }
83
84 void AVDASharedState::CodecChanged(MediaCodecBridge* codec) {
85 for (auto& image_kv : codec_images_)
86 image_kv.second->CodecChanged(codec);
87 release_time_ = base::TimeTicks();
88 }
89
90 void AVDASharedState::SetImageForPicture(int picture_buffer_id,
91 AVDACodecImage* image) {
92 if (!image) {
93 DCHECK(codec_images_.find(picture_buffer_id) != codec_images_.end());
94 codec_images_.erase(picture_buffer_id);
95 return;
96 }
97
98 DCHECK(codec_images_.find(picture_buffer_id) == codec_images_.end());
99 codec_images_[picture_buffer_id] = image;
100 }
101
102 AVDACodecImage* AVDASharedState::GetImageForPicture(
103 int picture_buffer_id) const {
104 auto it = codec_images_.find(picture_buffer_id);
105 return it == codec_images_.end() ? nullptr : it->second;
106 } 133 }
107 134
108 void AVDASharedState::RenderCodecBufferToSurfaceTexture( 135 void AVDASharedState::RenderCodecBufferToSurfaceTexture(
109 MediaCodecBridge* codec, 136 MediaCodecBridge* codec,
110 int codec_buffer_index) { 137 int codec_buffer_index) {
111 if (!release_time_.is_null()) 138 if (!release_time_.is_null())
112 WaitForFrameAvailable(); 139 WaitForFrameAvailable();
113 codec->ReleaseOutputBuffer(codec_buffer_index, true); 140 codec->ReleaseOutputBuffer(codec_buffer_index, true);
114 release_time_ = base::TimeTicks::Now(); 141 release_time_ = base::TimeTicks::Now();
115 } 142 }
116 143
117 void AVDASharedState::UpdateTexImage() { 144 void AVDASharedState::UpdateTexImage() {
118 surface_texture_->UpdateTexImage(); 145 surface_texture_->UpdateTexImage();
119 // Helpfully, this is already column major. 146 // Helpfully, this is already column major.
120 surface_texture_->GetTransformMatrix(gl_matrix_); 147 surface_texture_->GetTransformMatrix(gl_matrix_);
121 } 148 }
122 149
123 void AVDASharedState::GetTransformMatrix(float matrix[16]) const { 150 void AVDASharedState::GetTransformMatrix(float matrix[16]) const {
124 memcpy(matrix, gl_matrix_, sizeof(gl_matrix_)); 151 memcpy(matrix, gl_matrix_, sizeof(gl_matrix_));
125 } 152 }
126 153
127 } // namespace media 154 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698