Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / utility / media_galleries / media_metadata_parser.cc
blob9475bb877e683606002314e3ee2d203458678105
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/memory/linked_ptr.h"
11 #include "base/message_loop/message_loop.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"
19 namespace MediaGalleries = extensions::api::media_galleries;
21 namespace metadata {
23 namespace {
25 void SetStringScopedPtr(const std::string& value,
26 scoped_ptr<std::string>* destination) {
27 DCHECK(destination);
28 if (!value.empty())
29 destination->reset(new std::string(value));
32 void SetIntScopedPtr(int value, scoped_ptr<int>* destination) {
33 DCHECK(destination);
34 if (value >= 0)
35 destination->reset(new int(value));
38 void SetDoubleScopedPtr(double value, scoped_ptr<double>* destination) {
39 DCHECK(destination);
40 if (value >= 0)
41 destination->reset(new double(value));
44 void SetBoolScopedPtr(bool value, scoped_ptr<bool>* destination) {
45 DCHECK(destination);
46 destination->reset(new bool(value));
49 // This runs on |media_thread_|, as the underlying FFmpeg operation is
50 // blocking, and the utility thread must not be blocked, so the media file
51 // bytes can be sent from the browser process to the utility process.
52 scoped_ptr<MediaMetadataParser::MediaMetadata> ParseAudioVideoMetadata(
53 media::DataSource* source,
54 scoped_ptr<MediaMetadataParser::MediaMetadata> metadata) {
55 DCHECK(source);
56 DCHECK(metadata.get());
57 media::AudioVideoMetadataExtractor extractor;
59 if (!extractor.Extract(source))
60 return metadata.Pass();
62 if (extractor.duration() >= 0)
63 metadata->duration.reset(new double(extractor.duration()));
65 if (extractor.height() >= 0 && extractor.width() >= 0) {
66 metadata->height.reset(new int(extractor.height()));
67 metadata->width.reset(new int(extractor.width()));
70 SetStringScopedPtr(extractor.artist(), &metadata->artist);
71 SetStringScopedPtr(extractor.album(), &metadata->album);
72 SetStringScopedPtr(extractor.artist(), &metadata->artist);
73 SetStringScopedPtr(extractor.comment(), &metadata->comment);
74 SetStringScopedPtr(extractor.copyright(), &metadata->copyright);
75 SetIntScopedPtr(extractor.disc(), &metadata->disc);
76 SetStringScopedPtr(extractor.genre(), &metadata->genre);
77 SetStringScopedPtr(extractor.language(), &metadata->language);
78 SetIntScopedPtr(extractor.rotation(), &metadata->rotation);
79 SetStringScopedPtr(extractor.title(), &metadata->title);
80 SetIntScopedPtr(extractor.track(), &metadata->track);
82 for (media::AudioVideoMetadataExtractor::StreamInfoVector::const_iterator it =
83 extractor.stream_infos().begin();
84 it != extractor.stream_infos().end(); ++it) {
85 linked_ptr<MediaGalleries::StreamInfo> stream_info(
86 new MediaGalleries::StreamInfo);
87 stream_info->type = it->type;
89 for (std::map<std::string, std::string>::const_iterator tag_it =
90 it->tags.begin();
91 tag_it != it->tags.end(); ++tag_it) {
92 stream_info->tags.additional_properties.SetString(tag_it->first,
93 tag_it->second);
96 metadata->raw_tags.push_back(stream_info);
99 return metadata.Pass();
102 void FinishParseImageMetadata(
103 ImageMetadataExtractor* extractor,
104 scoped_ptr<MediaMetadataParser::MediaMetadata> metadata,
105 MediaMetadataParser::MetadataCallback callback,
106 bool extract_success) {
107 DCHECK(extractor);
108 DCHECK(metadata.get());
110 if (!extract_success) {
111 callback.Run(metadata.Pass());
112 return;
115 SetIntScopedPtr(extractor->height(), &metadata->height);
116 SetIntScopedPtr(extractor->width(), &metadata->width);
118 SetIntScopedPtr(extractor->rotation(), &metadata->rotation);
120 SetDoubleScopedPtr(extractor->x_resolution(), &metadata->x_resolution);
121 SetDoubleScopedPtr(extractor->y_resolution(), &metadata->y_resolution);
122 SetBoolScopedPtr(extractor->flash_fired(), &metadata->flash_fired);
123 SetStringScopedPtr(extractor->camera_make(), &metadata->camera_make);
124 SetStringScopedPtr(extractor->camera_model(), &metadata->camera_model);
125 SetDoubleScopedPtr(extractor->exposure_time_sec(),
126 &metadata->exposure_time_seconds);
128 SetDoubleScopedPtr(extractor->f_number(), &metadata->f_number);
129 SetDoubleScopedPtr(extractor->focal_length_mm(), &metadata->focal_length_mm);
130 SetDoubleScopedPtr(extractor->iso_equivalent(), &metadata->iso_equivalent);
132 callback.Run(metadata.Pass());
135 } // namespace
137 MediaMetadataParser::MediaMetadataParser(media::DataSource* source,
138 const std::string& mime_type)
139 : source_(source),
140 mime_type_(mime_type) {
143 MediaMetadataParser::~MediaMetadataParser() {}
145 void MediaMetadataParser::Start(const MetadataCallback& callback) {
146 scoped_ptr<MediaMetadata> metadata(new MediaMetadata);
147 metadata->mime_type = mime_type_;
149 if (StartsWithASCII(mime_type_, "audio/", true) ||
150 StartsWithASCII(mime_type_, "video/", true)) {
151 media_thread_.reset(new base::Thread("media_thread"));
152 CHECK(media_thread_->Start());
153 base::PostTaskAndReplyWithResult(
154 media_thread_->message_loop_proxy(),
155 FROM_HERE,
156 base::Bind(&ParseAudioVideoMetadata, source_, base::Passed(&metadata)),
157 callback);
158 return;
161 if (StartsWithASCII(mime_type_, "image/", true)) {
162 ImageMetadataExtractor* extractor = new ImageMetadataExtractor;
163 extractor->Extract(
164 source_,
165 base::Bind(&FinishParseImageMetadata, base::Owned(extractor),
166 base::Passed(&metadata), callback));
167 return;
170 // TODO(tommycli): Implement for image mime types.
171 callback.Run(metadata.Pass());
174 } // namespace metadata