OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filters/ffmpeg_glue.h" | 5 #include "media/filters/ffmpeg_glue.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
8 #include "base/synchronization/lock.h" | 9 #include "base/synchronization/lock.h" |
9 #include "media/ffmpeg/ffmpeg_common.h" | 10 #include "media/ffmpeg/ffmpeg_common.h" |
10 | 11 |
11 namespace media { | 12 namespace media { |
12 | 13 |
13 // Internal buffer size used by AVIO for reading. | 14 // Internal buffer size used by AVIO for reading. |
14 // TODO(dalecurtis): Experiment with this buffer size and measure impact on | 15 // TODO(dalecurtis): Experiment with this buffer size and measure impact on |
15 // performance. Currently we want to use 32kb to preserve existing behavior | 16 // performance. Currently we want to use 32kb to preserve existing behavior |
16 // with the previous URLProtocol based approach. | 17 // with the previous URLProtocol based approach. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 return 0; | 77 return 0; |
77 | 78 |
78 case AV_LOCK_DESTROY: | 79 case AV_LOCK_DESTROY: |
79 delete static_cast<base::Lock*>(*lock); | 80 delete static_cast<base::Lock*>(*lock); |
80 *lock = NULL; | 81 *lock = NULL; |
81 return 0; | 82 return 0; |
82 } | 83 } |
83 return 1; | 84 return 1; |
84 } | 85 } |
85 | 86 |
86 static bool InitializeFFmpegInternal() { | 87 // FFmpeg must only be initialized once, so use a LazyInstance to ensure this. |
87 // Before doing anything disable logging as it interferes with layout tests. | 88 class FFmpegInitializer { |
88 av_log_set_level(AV_LOG_QUIET); | 89 public: |
90 bool initialized() { return initialized_; } | |
89 | 91 |
90 // Register our protocol glue code with FFmpeg. | 92 private: |
91 if (av_lockmgr_register(&LockManagerOperation) != 0) | 93 friend struct base::DefaultLazyInstanceTraits<FFmpegInitializer>; |
92 return false; | |
93 | 94 |
94 // Now register the rest of FFmpeg. | 95 FFmpegInitializer() |
95 av_register_all(); | 96 : initialized_(false) { |
96 return true; | 97 // Before doing anything disable logging as it interferes with layout tests. |
97 } | 98 av_log_set_level(AV_LOG_QUIET); |
99 | |
100 // Register our protocol glue code with FFmpeg. | |
101 if (av_lockmgr_register(&LockManagerOperation) != 0) | |
102 return; | |
103 | |
104 // Now register the rest of FFmpeg. | |
105 av_register_all(); | |
106 | |
107 initialized_ = true; | |
108 } | |
109 | |
110 ~FFmpegInitializer() { | |
scherkus (not reviewing)
2012/11/02 23:39:28
I wonder if this ever gets called :)
DaleCurtis
2012/11/02 23:45:55
Yes, unless you declare it as:
static base::LazyI
scherkus (not reviewing)
2012/11/02 23:48:05
I'm ok w/ a leaky FFmpeg initializer. This is esse
DaleCurtis
2012/11/02 23:49:39
Done.
| |
111 if (initialized_) | |
112 av_lockmgr_register(NULL); | |
113 } | |
114 | |
115 bool initialized_; | |
116 | |
117 DISALLOW_COPY_AND_ASSIGN(FFmpegInitializer); | |
118 }; | |
98 | 119 |
99 void FFmpegGlue::InitializeFFmpeg() { | 120 void FFmpegGlue::InitializeFFmpeg() { |
100 // FFmpeg only needs to be initialized once. | 121 static base::LazyInstance<FFmpegInitializer> li = LAZY_INSTANCE_INITIALIZER; |
101 static const bool kStatus = InitializeFFmpegInternal(); | 122 CHECK(li.Get().initialized()); |
102 CHECK(kStatus); | |
103 } | 123 } |
104 | 124 |
105 FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) | 125 FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) |
106 : open_called_(false) { | 126 : open_called_(false) { |
107 InitializeFFmpeg(); | 127 InitializeFFmpeg(); |
108 | 128 |
109 // Initialize an AVIOContext using our custom read and seek operations. Don't | 129 // Initialize an AVIOContext using our custom read and seek operations. Don't |
110 // keep pointers to the buffer since FFmpeg may reallocate it on the fly. It | 130 // keep pointers to the buffer since FFmpeg may reallocate it on the fly. It |
111 // will be cleaned up | 131 // will be cleaned up |
112 format_context_ = avformat_alloc_context(); | 132 format_context_ = avformat_alloc_context(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 avcodec_close(stream->codec); | 195 avcodec_close(stream->codec); |
176 } | 196 } |
177 } | 197 } |
178 } | 198 } |
179 | 199 |
180 avformat_close_input(&format_context_); | 200 avformat_close_input(&format_context_); |
181 av_free(avio_context_->buffer); | 201 av_free(avio_context_->buffer); |
182 } | 202 } |
183 | 203 |
184 } // namespace media | 204 } // namespace media |
OLD | NEW |