Chromium Code Reviews| 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 |