Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: media/base/audio_video_metadata_extractor.cc

Issue 121383002: Media Galleries API Metadata: Add audio video metadata extractor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "media/base/audio_video_metadata_extractor.h"
6
7 #include <map>
Lei Zhang 2014/01/07 21:44:25 nit: remove
tommycli 2014/01/07 23:12:36 Done.
8
9 #include "base/bind.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/time/time.h"
13 #include "media/ffmpeg/ffmpeg_common.h"
14 #include "media/filters/blocking_url_protocol.h"
15 #include "media/filters/ffmpeg_glue.h"
16
17 namespace media {
18
19 namespace {
20
21 static void OnError(bool* called) {
Lei Zhang 2014/01/07 21:44:25 nit: no need for static
Lei Zhang 2014/01/07 21:44:25 Isn't |succeeded| more clear than |called| ?
tommycli 2014/01/07 23:12:36 Done.
tommycli 2014/01/07 23:12:36 Done.
22 *called = false;
23 }
24
25 // Returns true if the |expected_key| matches |key_lower|.
26 bool ExtractString(AVDictionaryEntry* tag, const std::string& key_lower,
27 const std::string& expected_key, std::string* destination) {
28 if (key_lower != expected_key)
29 return false;
30
31 if (destination->empty())
32 *destination = tag->value;
33
34 return true;
35 }
36
37 // Returns true if the |expected_key| matches |key_lower|.
38 bool ExtractInt(AVDictionaryEntry* tag, const std::string& key_lower,
39 const std::string& expected_key, int* destination) {
40 if (key_lower != expected_key)
41 return false;
42
43 int temporary = -1;
44 if (base::StringToInt(tag->value, &temporary) && temporary >= 0 &&
45 *destination < 0) {
Lei Zhang 2014/01/07 21:44:25 it's cheaper to check *dest first before doing the
tommycli 2014/01/07 23:12:36 Done.
46 *destination = temporary;
47 }
48
49 return true;
50 }
51
52 } // namespace
53
54 AudioVideoMetadataExtractor::AudioVideoMetadataExtractor()
55 : extracted_(false),
56 duration_(-1),
57 width_(-1),
58 height_(-1),
59 disc_(-1),
60 track_(-1) {
61 }
62
63 AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
64 }
65
66 bool AudioVideoMetadataExtractor::Extract(media::DataSource* source) {
67 DCHECK(!extracted_);
68
69 bool read_ok = true;
70 media::BlockingUrlProtocol protocol(source, base::Bind(&OnError, &read_ok));
71 media::FFmpegGlue glue(&protocol);
72 AVFormatContext* format_context = glue.format_context();
73
74 if (!glue.OpenContext())
75 return false;
76
77 if (!read_ok)
78 return false;
79
80 if (!format_context->iformat)
81 return false;
82
83 if (avformat_find_stream_info(format_context, NULL) < 0)
84 return false;
85
86 if (format_context->duration != AV_NOPTS_VALUE)
87 duration_ = static_cast<double>(format_context->duration) / AV_TIME_BASE;
88
89 ExtractDictionary(format_context->metadata);
90
91 for (unsigned int i = 0; i < format_context->nb_streams; ++i) {
Lei Zhang 2014/01/07 21:44:25 Isn't |format_context->nb_streams| an int, and the
tommycli 2014/01/07 23:12:36 I believe nb_streams is an unsigned int.
92 AVStream* stream = format_context->streams[i];
93 if (!stream)
94 continue;
95
96 // Ignore attached pictures for metadata extraction.
97 if ((stream->disposition & AV_DISPOSITION_ATTACHED_PIC) != 0)
98 continue;
99
100 // Extract dictionary from streams also. Needed for containers that attach
101 // metadata to contained streams instead the container itself, like OGG.
102 ExtractDictionary(stream->metadata);
103
104 if (!stream->codec)
105 continue;
106
107 // Extract dimensions of largest stream that's not an attached picture.
108 if (stream->codec->width > 0 && stream->codec->width > width_ &&
109 stream->codec->height > 0 && stream->codec->height > height_) {
110 width_ = stream->codec->width;
111 height_ = stream->codec->height;
112 }
113 }
114
115 extracted_ = true;
116 return true;
117 }
118
119 double AudioVideoMetadataExtractor::duration() const {
120 DCHECK(extracted_);
121 return duration_;
122 }
123
124 int AudioVideoMetadataExtractor::width() const {
125 DCHECK(extracted_);
126 return width_;
127 }
128
129 int AudioVideoMetadataExtractor::height() const {
130 DCHECK(extracted_);
131 return height_;
132 }
133
134 const std::string& AudioVideoMetadataExtractor::album() const {
135 DCHECK(extracted_);
136 return album_;
137 }
138
139 const std::string& AudioVideoMetadataExtractor::artist() const {
140 DCHECK(extracted_);
141 return artist_;
142 }
143
144 const std::string& AudioVideoMetadataExtractor::comment() const {
145 DCHECK(extracted_);
146 return comment_;
147 }
148
149 const std::string& AudioVideoMetadataExtractor::copyright() const {
150 DCHECK(extracted_);
151 return copyright_;
152 }
153
154 const std::string& AudioVideoMetadataExtractor::date() const {
155 DCHECK(extracted_);
156 return date_;
157 }
158
159 int AudioVideoMetadataExtractor::disc() const {
160 DCHECK(extracted_);
161 return disc_;
162 }
163
164 const std::string& AudioVideoMetadataExtractor::encoder() const {
165 DCHECK(extracted_);
166 return encoder_;
167 }
168
169 const std::string& AudioVideoMetadataExtractor::encoded_by() const {
170 DCHECK(extracted_);
171 return encoded_by_;
172 }
173
174 const std::string& AudioVideoMetadataExtractor::genre() const {
175 DCHECK(extracted_);
176 return genre_;
177 }
178
179 const std::string& AudioVideoMetadataExtractor::language() const {
180 DCHECK(extracted_);
181 return language_;
182 }
183
184 const std::string& AudioVideoMetadataExtractor::title() const {
185 DCHECK(extracted_);
186 return title_;
187 }
188
189 int AudioVideoMetadataExtractor::track() const {
190 DCHECK(extracted_);
191 return track_;
192 }
193
194 void AudioVideoMetadataExtractor::ExtractDictionary(AVDictionary* metadata) {
195 if (!metadata)
196 return;
197
198 AVDictionaryEntry* tag = NULL;
199 while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
200 std::string key = tag->key;
201 StringToLowerASCII(&key);
Lei Zhang 2014/01/07 21:44:25 Probably better to do this in ExtractString(), rat
tommycli 2014/01/07 23:12:36 Done.
202
203 // Try extracting all the defined keys.
204 if (ExtractString(tag, key, "album", &album_)) continue;
205 if (ExtractString(tag, key, "artist", &artist_)) continue;
206 if (ExtractString(tag, key, "comment", &comment_)) continue;
207 if (ExtractString(tag, key, "copyright", &copyright_)) continue;
208 if (ExtractString(tag, key, "date", &date_)) continue;
209 if (ExtractInt(tag, key, "disc", &disc_)) continue;
210 if (ExtractString(tag, key, "encoder", &encoder_)) continue;
211 if (ExtractString(tag, key, "encoded_by", &encoded_by_)) continue;
212 if (ExtractString(tag, key, "genre", &genre_)) continue;
213 if (ExtractString(tag, key, "language", &language_)) continue;
214 if (ExtractString(tag, key, "title", &title_)) continue;
215 if (ExtractInt(tag, key, "track", &track_)) continue;
216 }
217 }
218
219 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698