OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <iostream> | 5 #include <iostream> |
6 #include <signal.h> | 6 #include <signal.h> |
7 #include <X11/keysym.h> | 7 #include <X11/keysym.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "media/tools/player_x11/x11_video_renderer.h" | 45 #include "media/tools/player_x11/x11_video_renderer.h" |
46 typedef X11VideoRenderer Renderer; | 46 typedef X11VideoRenderer Renderer; |
47 #else | 47 #else |
48 #error No video renderer defined. | 48 #error No video renderer defined. |
49 #endif | 49 #endif |
50 | 50 |
51 Display* g_display = NULL; | 51 Display* g_display = NULL; |
52 Window g_window = 0; | 52 Window g_window = 0; |
53 bool g_running = false; | 53 bool g_running = false; |
54 | 54 |
55 void Quit(MessageLoop* message_loop) { | 55 class MessageLoopQuitter { |
56 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 56 public: |
57 } | 57 explicit MessageLoopQuitter(MessageLoop* loop) : loop_(loop) {} |
| 58 void Quit(media::PipelineStatus status) { |
| 59 loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 60 delete this; |
| 61 } |
| 62 private: |
| 63 MessageLoop* loop_; |
| 64 DISALLOW_COPY_AND_ASSIGN(MessageLoopQuitter); |
| 65 }; |
58 | 66 |
59 // Initialize X11. Returns true if successful. This method creates the X11 | 67 // Initialize X11. Returns true if successful. This method creates the X11 |
60 // window. Further initialization is done in X11VideoRenderer. | 68 // window. Further initialization is done in X11VideoRenderer. |
61 bool InitX11() { | 69 bool InitX11() { |
62 g_display = XOpenDisplay(NULL); | 70 g_display = XOpenDisplay(NULL); |
63 if (!g_display) { | 71 if (!g_display) { |
64 std::cout << "Error - cannot open display" << std::endl; | 72 std::cout << "Error - cannot open display" << std::endl; |
65 return false; | 73 return false; |
66 } | 74 } |
67 | 75 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 127 } |
120 collection->AddVideoRenderer(new Renderer(g_display, | 128 collection->AddVideoRenderer(new Renderer(g_display, |
121 g_window, | 129 g_window, |
122 paint_message_loop)); | 130 paint_message_loop)); |
123 | 131 |
124 if (enable_audio) | 132 if (enable_audio) |
125 collection->AddAudioRenderer(new media::AudioRendererImpl()); | 133 collection->AddAudioRenderer(new media::AudioRendererImpl()); |
126 else | 134 else |
127 collection->AddAudioRenderer(new media::NullAudioRenderer()); | 135 collection->AddAudioRenderer(new media::NullAudioRenderer()); |
128 | 136 |
129 // Create and start the pipeline. | 137 // Create the pipeline and start it. |
130 *pipeline = new media::PipelineImpl(message_loop); | 138 *pipeline = new media::PipelineImpl(message_loop); |
131 (*pipeline)->Start(collection.release(), filename, NULL); | 139 media::PipelineStatusNotification note; |
| 140 (*pipeline)->Start(collection.release(), filename, note.Callback()); |
132 | 141 |
133 // Wait until the pipeline is fully initialized. | 142 // Wait until the pipeline is fully initialized. |
134 while (true) { | 143 note.Wait(); |
135 base::PlatformThread::Sleep(100); | 144 if (note.status() != media::PIPELINE_OK) { |
136 if ((*pipeline)->IsInitialized()) | 145 std::cout << "InitPipeline: " << note.status() << std::endl; |
137 break; | 146 (*pipeline)->Stop(NULL); |
138 if ((*pipeline)->GetError() != media::PIPELINE_OK) { | 147 return false; |
139 std::cout << "InitPipeline: " << (*pipeline)->GetError() << std::endl; | |
140 (*pipeline)->Stop(NULL); | |
141 return false; | |
142 } | |
143 } | 148 } |
144 | 149 |
145 // And starts the playback. | 150 // And start the playback. |
146 (*pipeline)->SetPlaybackRate(1.0f); | 151 (*pipeline)->SetPlaybackRate(1.0f); |
147 return true; | 152 return true; |
148 } | 153 } |
149 | 154 |
150 void TerminateHandler(int signal) { | 155 void TerminateHandler(int signal) { |
151 g_running = false; | 156 g_running = false; |
152 } | 157 } |
153 | 158 |
154 void PeriodicalUpdate( | 159 void PeriodicalUpdate( |
155 media::PipelineImpl* pipeline, | 160 media::PipelineImpl* pipeline, |
156 MessageLoop* message_loop, | 161 MessageLoop* message_loop, |
157 bool audio_only) { | 162 bool audio_only) { |
158 if (!g_running) { | 163 if (!g_running) { |
159 // interrupt signal is received during lat time period. | 164 // interrupt signal was received during last time period. |
160 // Quit message_loop only when pipeline is fully stopped. | 165 // Quit message_loop only when pipeline is fully stopped. |
161 pipeline->Stop(media::TaskToCallbackAdapter::NewCallback( | 166 MessageLoopQuitter* quitter = new MessageLoopQuitter(message_loop); |
162 NewRunnableFunction(Quit, message_loop))); | 167 pipeline->Stop(NewCallback(quitter, &MessageLoopQuitter::Quit)); |
163 return; | 168 return; |
164 } | 169 } |
165 | 170 |
166 // Consume all the X events | 171 // Consume all the X events |
167 while (XPending(g_display)) { | 172 while (XPending(g_display)) { |
168 XEvent e; | 173 XEvent e; |
169 XNextEvent(g_display, &e); | 174 XNextEvent(g_display, &e); |
170 switch (e.type) { | 175 switch (e.type) { |
171 case Expose: | 176 case Expose: |
172 if (!audio_only) { | 177 if (!audio_only) { |
(...skipping 19 matching lines...) Expand all Loading... |
192 base::TimeDelta time = pipeline->GetMediaDuration(); | 197 base::TimeDelta time = pipeline->GetMediaDuration(); |
193 pipeline->Seek(time*e.xbutton.x/width, NULL); | 198 pipeline->Seek(time*e.xbutton.x/width, NULL); |
194 } | 199 } |
195 break; | 200 break; |
196 case KeyPress: | 201 case KeyPress: |
197 { | 202 { |
198 KeySym key = XKeycodeToKeysym(g_display, e.xkey.keycode, 0); | 203 KeySym key = XKeycodeToKeysym(g_display, e.xkey.keycode, 0); |
199 if (key == XK_Escape) { | 204 if (key == XK_Escape) { |
200 g_running = false; | 205 g_running = false; |
201 // Quit message_loop only when pipeline is fully stopped. | 206 // Quit message_loop only when pipeline is fully stopped. |
202 pipeline->Stop(media::TaskToCallbackAdapter::NewCallback( | 207 MessageLoopQuitter* quitter = new MessageLoopQuitter(message_loop); |
203 NewRunnableFunction(Quit, message_loop))); | 208 pipeline->Stop(NewCallback(quitter, &MessageLoopQuitter::Quit)); |
204 return; | 209 return; |
205 } else if (key == XK_space) { | 210 } else if (key == XK_space) { |
206 if (pipeline->GetPlaybackRate() < 0.01f) // paused | 211 if (pipeline->GetPlaybackRate() < 0.01f) // paused |
207 pipeline->SetPlaybackRate(1.0f); | 212 pipeline->SetPlaybackRate(1.0f); |
208 else | 213 else |
209 pipeline->SetPlaybackRate(0.0f); | 214 pipeline->SetPlaybackRate(0.0f); |
210 } | 215 } |
211 } | 216 } |
212 break; | 217 break; |
213 default: | 218 default: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 282 } |
278 | 283 |
279 // Cleanup tasks. | 284 // Cleanup tasks. |
280 message_loop_factory.reset(); | 285 message_loop_factory.reset(); |
281 | 286 |
282 thread->Stop(); | 287 thread->Stop(); |
283 XDestroyWindow(g_display, g_window); | 288 XDestroyWindow(g_display, g_window); |
284 XCloseDisplay(g_display); | 289 XCloseDisplay(g_display); |
285 return 0; | 290 return 0; |
286 } | 291 } |
OLD | NEW |