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/logging.h" | 7 #include "base/logging.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 return false; | 93 return false; |
94 | 94 |
95 // Now register the rest of FFmpeg. | 95 // Now register the rest of FFmpeg. |
96 av_register_all(); | 96 av_register_all(); |
97 return true; | 97 return true; |
98 }(); | 98 }(); |
99 | 99 |
100 CHECK(initialized); | 100 CHECK(initialized); |
101 } | 101 } |
102 | 102 |
103 FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) | 103 FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) { |
104 : open_called_(false) { | |
105 InitializeFFmpeg(); | 104 InitializeFFmpeg(); |
106 | 105 |
107 // Initialize an AVIOContext using our custom read and seek operations. Don't | 106 // Initialize an AVIOContext using our custom read and seek operations. Don't |
108 // keep pointers to the buffer since FFmpeg may reallocate it on the fly. It | 107 // keep pointers to the buffer since FFmpeg may reallocate it on the fly. It |
109 // will be cleaned up | 108 // will be cleaned up |
110 format_context_ = avformat_alloc_context(); | 109 format_context_ = avformat_alloc_context(); |
111 avio_context_.reset(avio_alloc_context( | 110 avio_context_.reset(avio_alloc_context( |
112 static_cast<unsigned char*>(av_malloc(kBufferSize)), kBufferSize, 0, | 111 static_cast<unsigned char*>(av_malloc(kBufferSize)), kBufferSize, 0, |
113 protocol, &AVIOReadOperation, nullptr, &AVIOSeekOperation)); | 112 protocol, &AVIOReadOperation, nullptr, &AVIOSeekOperation)); |
114 | 113 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 149 |
151 const int64_t pos = AVIOSeekOperation(avio_context_->opaque, 0, SEEK_SET); | 150 const int64_t pos = AVIOSeekOperation(avio_context_->opaque, 0, SEEK_SET); |
152 if (pos < 0) | 151 if (pos < 0) |
153 return false; | 152 return false; |
154 | 153 |
155 const int num_read = | 154 const int num_read = |
156 AVIOReadOperation(avio_context_->opaque, buffer.data(), buffer.size()); | 155 AVIOReadOperation(avio_context_->opaque, buffer.data(), buffer.size()); |
157 if (num_read < container_names::kMinimumContainerSize) | 156 if (num_read < container_names::kMinimumContainerSize) |
158 return false; | 157 return false; |
159 | 158 |
160 UMA_HISTOGRAM_SPARSE_SLOWLY( | 159 container_ = container_names::DetermineContainer(buffer.data(), num_read); |
161 "Media.DetectedContainer", | 160 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container_); |
162 container_names::DetermineContainer(buffer.data(), num_read)); | |
163 return false; | 161 return false; |
164 } else if (ret < 0) { | 162 } else if (ret < 0) { |
165 return false; | 163 return false; |
166 } | 164 } |
167 | 165 |
168 // Rely on ffmpeg's parsing if we're able to succesfully open the file. | 166 // Rely on ffmpeg's parsing if we're able to succesfully open the file. |
169 container_names::MediaContainerName container = | |
170 container_names::CONTAINER_UNKNOWN; | |
171 if (strcmp(format_context_->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) | 167 if (strcmp(format_context_->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) |
172 container = container_names::CONTAINER_MOV; | 168 container_ = container_names::CONTAINER_MOV; |
173 else if (strcmp(format_context_->iformat->name, "flac") == 0) | 169 else if (strcmp(format_context_->iformat->name, "flac") == 0) |
174 container = container_names::CONTAINER_FLAC; | 170 container_ = container_names::CONTAINER_FLAC; |
175 else if (strcmp(format_context_->iformat->name, "matroska,webm") == 0) | 171 else if (strcmp(format_context_->iformat->name, "matroska,webm") == 0) |
176 container = container_names::CONTAINER_WEBM; | 172 container_ = container_names::CONTAINER_WEBM; |
177 else if (strcmp(format_context_->iformat->name, "ogg") == 0) | 173 else if (strcmp(format_context_->iformat->name, "ogg") == 0) |
178 container = container_names::CONTAINER_OGG; | 174 container_ = container_names::CONTAINER_OGG; |
179 else if (strcmp(format_context_->iformat->name, "wav") == 0) | 175 else if (strcmp(format_context_->iformat->name, "wav") == 0) |
180 container = container_names::CONTAINER_WAV; | 176 container_ = container_names::CONTAINER_WAV; |
181 else if (strcmp(format_context_->iformat->name, "aac") == 0) | 177 else if (strcmp(format_context_->iformat->name, "aac") == 0) |
182 container = container_names::CONTAINER_AAC; | 178 container_ = container_names::CONTAINER_AAC; |
183 else if (strcmp(format_context_->iformat->name, "mp3") == 0) | 179 else if (strcmp(format_context_->iformat->name, "mp3") == 0) |
184 container = container_names::CONTAINER_MP3; | 180 container_ = container_names::CONTAINER_MP3; |
185 else if (strcmp(format_context_->iformat->name, "amr") == 0) | 181 else if (strcmp(format_context_->iformat->name, "amr") == 0) |
186 container = container_names::CONTAINER_AMR; | 182 container_ = container_names::CONTAINER_AMR; |
187 else if (strcmp(format_context_->iformat->name, "avi") == 0) | 183 else if (strcmp(format_context_->iformat->name, "avi") == 0) |
188 container = container_names::CONTAINER_AVI; | 184 container_ = container_names::CONTAINER_AVI; |
189 // TODO(jrummell): Remove GSM detection. http://crbug.com/711774 | 185 // TODO(jrummell): Remove GSM detection. http://crbug.com/711774 |
190 else if (strcmp(format_context_->iformat->name, "gsm") == 0) | 186 else if (strcmp(format_context_->iformat->name, "gsm") == 0) |
191 container = container_names::CONTAINER_GSM; | 187 container_ = container_names::CONTAINER_GSM; |
192 | 188 |
193 DCHECK_NE(container, container_names::CONTAINER_UNKNOWN); | 189 DCHECK_NE(container_, container_names::CONTAINER_UNKNOWN); |
194 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container); | 190 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container_); |
195 | 191 |
196 return true; | 192 return true; |
197 } | 193 } |
198 | 194 |
199 FFmpegGlue::~FFmpegGlue() { | 195 FFmpegGlue::~FFmpegGlue() { |
200 // In the event of avformat_open_input() failure, FFmpeg may sometimes free | 196 // In the event of avformat_open_input() failure, FFmpeg may sometimes free |
201 // our AVFormatContext behind the scenes, but leave the buffer alive. It will | 197 // our AVFormatContext behind the scenes, but leave the buffer alive. It will |
202 // helpfully set |format_context_| to nullptr in this case. | 198 // helpfully set |format_context_| to nullptr in this case. |
203 if (!format_context_) { | 199 if (!format_context_) { |
204 av_free(avio_context_->buffer); | 200 av_free(avio_context_->buffer); |
205 return; | 201 return; |
206 } | 202 } |
207 | 203 |
208 // If avformat_open_input() hasn't been called, we should simply free the | 204 // If avformat_open_input() hasn't been called, we should simply free the |
209 // AVFormatContext and buffer instead of using avformat_close_input(). | 205 // AVFormatContext and buffer instead of using avformat_close_input(). |
210 if (!open_called_) { | 206 if (!open_called_) { |
211 avformat_free_context(format_context_); | 207 avformat_free_context(format_context_); |
212 av_free(avio_context_->buffer); | 208 av_free(avio_context_->buffer); |
213 return; | 209 return; |
214 } | 210 } |
215 | 211 |
216 avformat_close_input(&format_context_); | 212 avformat_close_input(&format_context_); |
217 av_free(avio_context_->buffer); | 213 av_free(avio_context_->buffer); |
218 } | 214 } |
219 | 215 |
220 } // namespace media | 216 } // namespace media |
OLD | NEW |