Do not call FaviconHandler::OnUpdateFaviconURL() if there is no last committed naviga...
[chromium-blink-merge.git] / chrome / utility / media_galleries / media_metadata_parser.cc
blobb1fb81c53203784c1b1894c7a3f4e4b98e59bc9b
1 // Copyright 2013 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.
5 #include "chrome/utility/media_galleries/media_metadata_parser.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/memory/linked_ptr.h"
12 #include "base/strings/string_util.h"
13 #include "base/task_runner_util.h"
14 #include "base/threading/thread.h"
15 #include "chrome/utility/media_galleries/image_metadata_extractor.h"
16 #include "media/base/audio_video_metadata_extractor.h"
17 #include "media/base/data_source.h"
18 #include "net/base/mime_sniffer.h"
20 namespace MediaGalleries = extensions::api::media_galleries;
22 namespace metadata {
24 namespace {
26 void SetStringScopedPtr(const std::string& value,
27 scoped_ptr<std::string>* destination) {
28 DCHECK(destination);
29 if (!value.empty())
30 destination->reset(new std::string(value));
33 void SetIntScopedPtr(int value, scoped_ptr<int>* destination) {
34 DCHECK(destination);
35 if (value >= 0)
36 destination->reset(new int(value));
39 void SetDoubleScopedPtr(double value, scoped_ptr<double>* destination) {
40 DCHECK(destination);
41 if (value >= 0)
42 destination->reset(new double(value));
45 void SetBoolScopedPtr(bool value, scoped_ptr<bool>* destination) {
46 DCHECK(destination);
47 destination->reset(new bool(value));
50 // This runs on |media_thread_|, as the underlying FFmpeg operation is
51 // blocking, and the utility thread must not be blocked, so the media file
52 // bytes can be sent from the browser process to the utility process.
53 void ParseAudioVideoMetadata(
54 media::DataSource* source, bool get_attached_images,
55 MediaMetadataParser::MediaMetadata* metadata,
56 std::vector<AttachedImage>* attached_images) {
57 DCHECK(source);
58 DCHECK(metadata);
59 media::AudioVideoMetadataExtractor extractor;
61 if (!extractor.Extract(source, get_attached_images))
62 return;
64 if (extractor.duration() >= 0)
65 metadata->duration.reset(new double(extractor.duration()));
67 if (extractor.height() >= 0 && extractor.width() >= 0) {
68 metadata->height.reset(new int(extractor.height()));
69 metadata->width.reset(new int(extractor.width()));
72 SetStringScopedPtr(extractor.artist(), &metadata->artist);
73 SetStringScopedPtr(extractor.album(), &metadata->album);
74 SetStringScopedPtr(extractor.artist(), &metadata->artist);
75 SetStringScopedPtr(extractor.comment(), &metadata->comment);
76 SetStringScopedPtr(extractor.copyright(), &metadata->copyright);
77 SetIntScopedPtr(extractor.disc(), &metadata->disc);
78 SetStringScopedPtr(extractor.genre(), &metadata->genre);
79 SetStringScopedPtr(extractor.language(), &metadata->language);
80 SetIntScopedPtr(extractor.rotation(), &metadata->rotation);
81 SetStringScopedPtr(extractor.title(), &metadata->title);
82 SetIntScopedPtr(extractor.track(), &metadata->track);
84 for (media::AudioVideoMetadataExtractor::StreamInfoVector::const_iterator it =
85 extractor.stream_infos().begin();
86 it != extractor.stream_infos().end(); ++it) {
87 linked_ptr<MediaGalleries::StreamInfo> stream_info(
88 new MediaGalleries::StreamInfo);
89 stream_info->type = it->type;
91 for (std::map<std::string, std::string>::const_iterator tag_it =
92 it->tags.begin();
93 tag_it != it->tags.end(); ++tag_it) {
94 stream_info->tags.additional_properties.SetString(tag_it->first,
95 tag_it->second);
98 metadata->raw_tags.push_back(stream_info);
101 if (get_attached_images) {
102 for (std::vector<std::string>::const_iterator it =
103 extractor.attached_images_bytes().begin();
104 it != extractor.attached_images_bytes().end(); ++it) {
105 attached_images->push_back(AttachedImage());
106 attached_images->back().data = *it;
107 net::SniffMimeTypeFromLocalData(it->c_str(), it->length(),
108 &attached_images->back().type);
113 void FinishParseAudioVideoMetadata(
114 MediaMetadataParser::MetadataCallback callback,
115 MediaMetadataParser::MediaMetadata* metadata,
116 std::vector<AttachedImage>* attached_images) {
117 DCHECK(!callback.is_null());
118 DCHECK(metadata);
119 DCHECK(attached_images);
121 callback.Run(*metadata, *attached_images);
124 void FinishParseImageMetadata(
125 ImageMetadataExtractor* extractor, const std::string& mime_type,
126 MediaMetadataParser::MetadataCallback callback, bool extract_success) {
127 DCHECK(extractor);
128 MediaMetadataParser::MediaMetadata metadata;
129 metadata.mime_type = mime_type;
131 if (!extract_success) {
132 callback.Run(metadata, std::vector<AttachedImage>());
133 return;
136 SetIntScopedPtr(extractor->height(), &metadata.height);
137 SetIntScopedPtr(extractor->width(), &metadata.width);
139 SetIntScopedPtr(extractor->rotation(), &metadata.rotation);
141 SetDoubleScopedPtr(extractor->x_resolution(), &metadata.x_resolution);
142 SetDoubleScopedPtr(extractor->y_resolution(), &metadata.y_resolution);
143 SetBoolScopedPtr(extractor->flash_fired(), &metadata.flash_fired);
144 SetStringScopedPtr(extractor->camera_make(), &metadata.camera_make);
145 SetStringScopedPtr(extractor->camera_model(), &metadata.camera_model);
146 SetDoubleScopedPtr(extractor->exposure_time_sec(),
147 &metadata.exposure_time_seconds);
149 SetDoubleScopedPtr(extractor->f_number(), &metadata.f_number);
150 SetDoubleScopedPtr(extractor->focal_length_mm(), &metadata.focal_length_mm);
151 SetDoubleScopedPtr(extractor->iso_equivalent(), &metadata.iso_equivalent);
153 callback.Run(metadata, std::vector<AttachedImage>());
156 } // namespace
158 MediaMetadataParser::MediaMetadataParser(media::DataSource* source,
159 const std::string& mime_type,
160 bool get_attached_images)
161 : source_(source),
162 mime_type_(mime_type),
163 get_attached_images_(get_attached_images) {
166 MediaMetadataParser::~MediaMetadataParser() {}
168 void MediaMetadataParser::Start(const MetadataCallback& callback) {
169 if (base::StartsWith(mime_type_, "audio/", base::CompareCase::SENSITIVE) ||
170 base::StartsWith(mime_type_, "video/", base::CompareCase::SENSITIVE)) {
171 MediaMetadata* metadata = new MediaMetadata;
172 metadata->mime_type = mime_type_;
173 std::vector<AttachedImage>* attached_images =
174 new std::vector<AttachedImage>;
176 media_thread_.reset(new base::Thread("media_thread"));
177 CHECK(media_thread_->Start());
178 media_thread_->task_runner()->PostTaskAndReply(
179 FROM_HERE, base::Bind(&ParseAudioVideoMetadata, source_,
180 get_attached_images_, metadata, attached_images),
181 base::Bind(&FinishParseAudioVideoMetadata, callback,
182 base::Owned(metadata), base::Owned(attached_images)));
183 return;
186 if (base::StartsWith(mime_type_, "image/", base::CompareCase::SENSITIVE)) {
187 ImageMetadataExtractor* extractor = new ImageMetadataExtractor;
188 extractor->Extract(
189 source_,
190 base::Bind(&FinishParseImageMetadata, base::Owned(extractor),
191 mime_type_, callback));
192 return;
195 callback.Run(MediaMetadata(), std::vector<AttachedImage>());
198 } // namespace metadata