OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/Xlib.h> | 7 #include <X11/Xlib.h> |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
13 #include "base/thread.h" | 13 #include "base/thread.h" |
| 14 #include "base/waitable_event.h" |
14 #include "media/base/media.h" | 15 #include "media/base/media.h" |
15 #include "media/base/media_switches.h" | 16 #include "media/base/media_switches.h" |
16 #include "media/base/pipeline_impl.h" | 17 #include "media/base/pipeline_impl.h" |
17 #include "media/filters/audio_renderer_impl.h" | 18 #include "media/filters/audio_renderer_impl.h" |
18 #include "media/filters/ffmpeg_audio_decoder.h" | 19 #include "media/filters/ffmpeg_audio_decoder.h" |
19 #include "media/filters/ffmpeg_demuxer.h" | 20 #include "media/filters/ffmpeg_demuxer.h" |
20 #include "media/filters/ffmpeg_video_decoder.h" | 21 #include "media/filters/ffmpeg_video_decoder.h" |
21 #include "media/filters/file_data_source.h" | 22 #include "media/filters/file_data_source.h" |
22 #include "media/filters/null_audio_renderer.h" | 23 #include "media/filters/null_audio_renderer.h" |
23 #include "media/filters/omx_video_decoder.h" | 24 #include "media/filters/omx_video_decoder.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 XEvent e; | 135 XEvent e; |
135 XNextEvent(g_display, &e); | 136 XNextEvent(g_display, &e); |
136 if (e.type == Expose) { | 137 if (e.type == Expose) { |
137 if (!audio_only) { | 138 if (!audio_only) { |
138 // Tell the renderer to paint. | 139 // Tell the renderer to paint. |
139 DCHECK(Renderer::instance()); | 140 DCHECK(Renderer::instance()); |
140 Renderer::instance()->Paint(); | 141 Renderer::instance()->Paint(); |
141 } | 142 } |
142 } else if (e.type == ButtonPress) { | 143 } else if (e.type == ButtonPress) { |
143 g_running = false; | 144 g_running = false; |
144 message_loop->Quit(); | 145 // QuitNow is more responsive than Quit since renderer_base is till |
| 146 // posting paint messages. |
| 147 message_loop->QuitNow(); |
145 return; | 148 return; |
146 } | 149 } |
147 } | 150 } |
148 | 151 |
149 message_loop->PostDelayedTask(FROM_HERE, | 152 message_loop->PostDelayedTask(FROM_HERE, |
150 NewRunnableFunction(PeriodicalUpdate, message_loop, audio_only), 10); | 153 NewRunnableFunction(PeriodicalUpdate, message_loop, audio_only), 10); |
151 } | 154 } |
152 | 155 |
153 int main(int argc, char** argv) { | 156 int main(int argc, char** argv) { |
154 // Read arguments. | 157 // Read arguments. |
(...skipping 19 matching lines...) Expand all Loading... |
174 signal(SIGINT, &TerminateHandler); | 177 signal(SIGINT, &TerminateHandler); |
175 | 178 |
176 // Initialize X11. | 179 // Initialize X11. |
177 if (!InitX11()) | 180 if (!InitX11()) |
178 return 1; | 181 return 1; |
179 | 182 |
180 // Initialize the pipeline thread and the pipeline. | 183 // Initialize the pipeline thread and the pipeline. |
181 base::AtExitManager at_exit; | 184 base::AtExitManager at_exit; |
182 scoped_ptr<base::Thread> thread; | 185 scoped_ptr<base::Thread> thread; |
183 scoped_refptr<media::PipelineImpl> pipeline; | 186 scoped_refptr<media::PipelineImpl> pipeline; |
| 187 MessageLoop message_loop; |
184 thread.reset(new base::Thread("PipelineThread")); | 188 thread.reset(new base::Thread("PipelineThread")); |
185 thread->Start(); | 189 thread->Start(); |
186 if (InitPipeline(thread->message_loop(), filename.c_str(), | 190 if (InitPipeline(thread->message_loop(), filename.c_str(), |
187 enable_audio, &pipeline)) { | 191 enable_audio, &pipeline)) { |
188 // Main loop of the application. | 192 // Main loop of the application. |
189 g_running = true; | 193 g_running = true; |
190 | 194 |
191 // Check if video is present. | 195 // Check if video is present. |
192 audio_only = !pipeline->IsRendered(media::mime_type::kMajorTypeVideo); | 196 audio_only = !pipeline->IsRendered(media::mime_type::kMajorTypeVideo); |
193 | 197 |
194 MessageLoop message_loop; | |
195 if (!audio_only) { | 198 if (!audio_only) { |
196 // Tell the renderer to paint. | 199 // Tell the renderer to paint. |
197 DCHECK(Renderer::instance()); | 200 DCHECK(Renderer::instance()); |
198 Renderer::instance()->set_glx_thread_message_loop(&message_loop); | 201 Renderer::instance()->set_glx_thread_message_loop(&message_loop); |
199 } | 202 } |
200 | 203 |
201 message_loop.PostTask(FROM_HERE, | 204 message_loop.PostTask(FROM_HERE, |
202 NewRunnableFunction(PeriodicalUpdate, &message_loop, audio_only)); | 205 NewRunnableFunction(PeriodicalUpdate, &message_loop, audio_only)); |
203 message_loop.Run(); | 206 message_loop.Run(); |
204 | 207 |
205 pipeline->Stop(NULL); | 208 // Need to wait for pipeline to be fully stopped before stopping the thread. |
| 209 base::WaitableEvent event(false, false); |
| 210 pipeline->Stop(NewCallback(&event, &base::WaitableEvent::Signal)); |
| 211 event.Wait(); |
206 } else{ | 212 } else{ |
207 std::cout << "Pipeline initialization failed..." << std::endl; | 213 std::cout << "Pipeline initialization failed..." << std::endl; |
208 } | 214 } |
209 | 215 |
210 // Cleanup tasks. | 216 // Cleanup tasks. |
211 thread->Stop(); | 217 thread->Stop(); |
212 XDestroyWindow(g_display, g_window); | 218 XDestroyWindow(g_display, g_window); |
213 XCloseDisplay(g_display); | 219 XCloseDisplay(g_display); |
214 return 0; | 220 return 0; |
215 } | 221 } |
OLD | NEW |