| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/base/audio_video_metadata_extractor.h" | 5 #include "media/base/audio_video_metadata_extractor.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 int temporary = -1; | 41 int temporary = -1; |
| 42 if (*destination < 0 && base::StringToInt(tag->value, &temporary) && | 42 if (*destination < 0 && base::StringToInt(tag->value, &temporary) && |
| 43 temporary >= 0) { | 43 temporary >= 0) { |
| 44 *destination = temporary; | 44 *destination = temporary; |
| 45 } | 45 } |
| 46 | 46 |
| 47 return true; | 47 return true; |
| 48 } | 48 } |
| 49 | 49 |
| 50 // Set attached image size limit to 4MB. Chosen arbitrarily. |
| 51 const int kAttachedImageSizeLimit = 4 * 1024 * 1024; |
| 52 |
| 50 } // namespace | 53 } // namespace |
| 51 | 54 |
| 52 AudioVideoMetadataExtractor::StreamInfo::StreamInfo() {} | 55 AudioVideoMetadataExtractor::StreamInfo::StreamInfo() {} |
| 53 | 56 |
| 54 AudioVideoMetadataExtractor::StreamInfo::~StreamInfo() {} | 57 AudioVideoMetadataExtractor::StreamInfo::~StreamInfo() {} |
| 55 | 58 |
| 56 AudioVideoMetadataExtractor::AudioVideoMetadataExtractor() | 59 AudioVideoMetadataExtractor::AudioVideoMetadataExtractor() |
| 57 : extracted_(false), | 60 : extracted_(false), |
| 58 duration_(-1), | 61 duration_(-1), |
| 59 width_(-1), | 62 width_(-1), |
| 60 height_(-1), | 63 height_(-1), |
| 61 disc_(-1), | 64 disc_(-1), |
| 62 rotation_(-1), | 65 rotation_(-1), |
| 63 track_(-1) { | 66 track_(-1) { |
| 64 } | 67 } |
| 65 | 68 |
| 66 AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() { | 69 AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() { |
| 67 } | 70 } |
| 68 | 71 |
| 69 bool AudioVideoMetadataExtractor::Extract(DataSource* source) { | 72 bool AudioVideoMetadataExtractor::Extract(DataSource* source, |
| 73 bool extract_attached_images) { |
| 70 DCHECK(!extracted_); | 74 DCHECK(!extracted_); |
| 71 | 75 |
| 72 bool read_ok = true; | 76 bool read_ok = true; |
| 73 media::BlockingUrlProtocol protocol(source, base::Bind(&OnError, &read_ok)); | 77 media::BlockingUrlProtocol protocol(source, base::Bind(&OnError, &read_ok)); |
| 74 media::FFmpegGlue glue(&protocol); | 78 media::FFmpegGlue glue(&protocol); |
| 75 AVFormatContext* format_context = glue.format_context(); | 79 AVFormatContext* format_context = glue.format_context(); |
| 76 | 80 |
| 77 if (!glue.OpenContext()) | 81 if (!glue.OpenContext()) |
| 78 return false; | 82 return false; |
| 79 | 83 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 104 | 108 |
| 105 // Extract dictionary from streams also. Needed for containers that attach | 109 // Extract dictionary from streams also. Needed for containers that attach |
| 106 // metadata to contained streams instead the container itself, like OGG. | 110 // metadata to contained streams instead the container itself, like OGG. |
| 107 ExtractDictionary(stream->metadata, &info.tags); | 111 ExtractDictionary(stream->metadata, &info.tags); |
| 108 | 112 |
| 109 if (!stream->codec) | 113 if (!stream->codec) |
| 110 continue; | 114 continue; |
| 111 | 115 |
| 112 info.type = avcodec_get_name(stream->codec->codec_id); | 116 info.type = avcodec_get_name(stream->codec->codec_id); |
| 113 | 117 |
| 114 // Extract dimensions of largest stream that's not an attached picture. | 118 // Extract dimensions of largest stream that's not an attached image. |
| 115 if (stream->codec->width > 0 && stream->codec->width > width_ && | 119 if (stream->codec->width > 0 && stream->codec->width > width_ && |
| 116 stream->codec->height > 0 && stream->codec->height > height_) { | 120 stream->codec->height > 0 && stream->codec->height > height_) { |
| 117 width_ = stream->codec->width; | 121 width_ = stream->codec->width; |
| 118 height_ = stream->codec->height; | 122 height_ = stream->codec->height; |
| 119 } | 123 } |
| 124 |
| 125 // Extract attached image if requested. |
| 126 if (extract_attached_images && |
| 127 stream->disposition == AV_DISPOSITION_ATTACHED_PIC && |
| 128 stream->attached_pic.size > 0 && |
| 129 stream->attached_pic.size <= kAttachedImageSizeLimit && |
| 130 stream->attached_pic.data != NULL) { |
| 131 attached_images_bytes_.push_back(std::string()); |
| 132 attached_images_bytes_.back().assign( |
| 133 reinterpret_cast<const char*>(stream->attached_pic.data), |
| 134 stream->attached_pic.size); |
| 135 } |
| 120 } | 136 } |
| 121 | 137 |
| 122 extracted_ = true; | 138 extracted_ = true; |
| 123 return true; | 139 return true; |
| 124 } | 140 } |
| 125 | 141 |
| 126 double AudioVideoMetadataExtractor::duration() const { | 142 double AudioVideoMetadataExtractor::duration() const { |
| 127 DCHECK(extracted_); | 143 DCHECK(extracted_); |
| 128 return duration_; | 144 return duration_; |
| 129 } | 145 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 DCHECK(extracted_); | 218 DCHECK(extracted_); |
| 203 return track_; | 219 return track_; |
| 204 } | 220 } |
| 205 | 221 |
| 206 const std::vector<AudioVideoMetadataExtractor::StreamInfo>& | 222 const std::vector<AudioVideoMetadataExtractor::StreamInfo>& |
| 207 AudioVideoMetadataExtractor::stream_infos() const { | 223 AudioVideoMetadataExtractor::stream_infos() const { |
| 208 DCHECK(extracted_); | 224 DCHECK(extracted_); |
| 209 return stream_infos_; | 225 return stream_infos_; |
| 210 } | 226 } |
| 211 | 227 |
| 228 const std::vector<std::string>& |
| 229 AudioVideoMetadataExtractor::attached_images_bytes() const { |
| 230 DCHECK(extracted_); |
| 231 return attached_images_bytes_; |
| 232 } |
| 233 |
| 212 void AudioVideoMetadataExtractor::ExtractDictionary( | 234 void AudioVideoMetadataExtractor::ExtractDictionary( |
| 213 AVDictionary* metadata, TagDictionary* raw_tags) { | 235 AVDictionary* metadata, TagDictionary* raw_tags) { |
| 214 if (!metadata) | 236 if (!metadata) |
| 215 return; | 237 return; |
| 216 | 238 |
| 217 AVDictionaryEntry* tag = NULL; | 239 AVDictionaryEntry* tag = NULL; |
| 218 while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { | 240 while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { |
| 219 if (raw_tags->find(tag->key) == raw_tags->end()) | 241 if (raw_tags->find(tag->key) == raw_tags->end()) |
| 220 (*raw_tags)[tag->key] = tag->value; | 242 (*raw_tags)[tag->key] = tag->value; |
| 221 | 243 |
| 222 if (ExtractInt(tag, "rotate", &rotation_)) continue; | 244 if (ExtractInt(tag, "rotate", &rotation_)) continue; |
| 223 if (ExtractString(tag, "album", &album_)) continue; | 245 if (ExtractString(tag, "album", &album_)) continue; |
| 224 if (ExtractString(tag, "artist", &artist_)) continue; | 246 if (ExtractString(tag, "artist", &artist_)) continue; |
| 225 if (ExtractString(tag, "comment", &comment_)) continue; | 247 if (ExtractString(tag, "comment", &comment_)) continue; |
| 226 if (ExtractString(tag, "copyright", ©right_)) continue; | 248 if (ExtractString(tag, "copyright", ©right_)) continue; |
| 227 if (ExtractString(tag, "date", &date_)) continue; | 249 if (ExtractString(tag, "date", &date_)) continue; |
| 228 if (ExtractInt(tag, "disc", &disc_)) continue; | 250 if (ExtractInt(tag, "disc", &disc_)) continue; |
| 229 if (ExtractString(tag, "encoder", &encoder_)) continue; | 251 if (ExtractString(tag, "encoder", &encoder_)) continue; |
| 230 if (ExtractString(tag, "encoded_by", &encoded_by_)) continue; | 252 if (ExtractString(tag, "encoded_by", &encoded_by_)) continue; |
| 231 if (ExtractString(tag, "genre", &genre_)) continue; | 253 if (ExtractString(tag, "genre", &genre_)) continue; |
| 232 if (ExtractString(tag, "language", &language_)) continue; | 254 if (ExtractString(tag, "language", &language_)) continue; |
| 233 if (ExtractString(tag, "title", &title_)) continue; | 255 if (ExtractString(tag, "title", &title_)) continue; |
| 234 if (ExtractInt(tag, "track", &track_)) continue; | 256 if (ExtractInt(tag, "track", &track_)) continue; |
| 235 } | 257 } |
| 236 } | 258 } |
| 237 | 259 |
| 238 } // namespace media | 260 } // namespace media |
| OLD | NEW |