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

Unified 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: address thestig comments 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/audio_video_metadata_extractor.h ('k') | media/base/audio_video_metadata_extractor_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/audio_video_metadata_extractor.cc
diff --git a/media/base/audio_video_metadata_extractor.cc b/media/base/audio_video_metadata_extractor.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fe26d84313618ee614b2e82c7391f406b5f41562
--- /dev/null
+++ b/media/base/audio_video_metadata_extractor.cc
@@ -0,0 +1,213 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/audio_video_metadata_extractor.h"
+
+#include "base/bind.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/time/time.h"
+#include "media/ffmpeg/ffmpeg_common.h"
+#include "media/filters/blocking_url_protocol.h"
+#include "media/filters/ffmpeg_glue.h"
+
+namespace media {
+
+namespace {
+
+void OnError(bool* succeeded) {
+ *succeeded = false;
+}
+
+// Returns true if the |tag| matches |expected_key|.
+bool ExtractString(AVDictionaryEntry* tag, const char* expected_key,
+ std::string* destination) {
+ if (!LowerCaseEqualsASCII(std::string(tag->key), expected_key))
Lei Zhang 2014/01/07 23:20:03 Do you need to convert |tag->key| to a std::string
tommycli 2014/01/07 23:22:28 Yes, as the char* forms take an explicit start and
+ return false;
+
+ if (destination->empty())
+ *destination = tag->value;
+
+ return true;
+}
+
+// Returns true if the |tag| matches |expected_key|.
+bool ExtractInt(AVDictionaryEntry* tag, const char* expected_key,
+ int* destination) {
+ if (!LowerCaseEqualsASCII(std::string(tag->key), expected_key))
+ return false;
+
+ int temporary = -1;
+ if (*destination < 0 && base::StringToInt(tag->value, &temporary) &&
+ temporary >= 0) {
+ *destination = temporary;
+ }
+
+ return true;
+}
+
+} // namespace
+
+AudioVideoMetadataExtractor::AudioVideoMetadataExtractor()
+ : extracted_(false),
+ duration_(-1),
+ width_(-1),
+ height_(-1),
+ disc_(-1),
+ track_(-1) {
+}
+
+AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
+}
+
+bool AudioVideoMetadataExtractor::Extract(DataSource* source) {
+ DCHECK(!extracted_);
+
+ bool read_ok = true;
+ media::BlockingUrlProtocol protocol(source, base::Bind(&OnError, &read_ok));
+ media::FFmpegGlue glue(&protocol);
+ AVFormatContext* format_context = glue.format_context();
+
+ if (!glue.OpenContext())
+ return false;
+
+ if (!read_ok)
+ return false;
+
+ if (!format_context->iformat)
+ return false;
+
+ if (avformat_find_stream_info(format_context, NULL) < 0)
+ return false;
+
+ if (format_context->duration != AV_NOPTS_VALUE)
+ duration_ = static_cast<double>(format_context->duration) / AV_TIME_BASE;
+
+ ExtractDictionary(format_context->metadata);
+
+ for (unsigned int i = 0; i < format_context->nb_streams; ++i) {
+ AVStream* stream = format_context->streams[i];
+ if (!stream)
+ continue;
+
+ // Ignore attached pictures for metadata extraction.
+ if ((stream->disposition & AV_DISPOSITION_ATTACHED_PIC) != 0)
+ continue;
+
+ // Extract dictionary from streams also. Needed for containers that attach
+ // metadata to contained streams instead the container itself, like OGG.
+ ExtractDictionary(stream->metadata);
+
+ if (!stream->codec)
+ continue;
+
+ // Extract dimensions of largest stream that's not an attached picture.
+ if (stream->codec->width > 0 && stream->codec->width > width_ &&
+ stream->codec->height > 0 && stream->codec->height > height_) {
+ width_ = stream->codec->width;
+ height_ = stream->codec->height;
+ }
+ }
+
+ extracted_ = true;
+ return true;
+}
+
+double AudioVideoMetadataExtractor::duration() const {
+ DCHECK(extracted_);
+ return duration_;
+}
+
+int AudioVideoMetadataExtractor::width() const {
+ DCHECK(extracted_);
+ return width_;
+}
+
+int AudioVideoMetadataExtractor::height() const {
+ DCHECK(extracted_);
+ return height_;
+}
+
+const std::string& AudioVideoMetadataExtractor::album() const {
+ DCHECK(extracted_);
+ return album_;
+}
+
+const std::string& AudioVideoMetadataExtractor::artist() const {
+ DCHECK(extracted_);
+ return artist_;
+}
+
+const std::string& AudioVideoMetadataExtractor::comment() const {
+ DCHECK(extracted_);
+ return comment_;
+}
+
+const std::string& AudioVideoMetadataExtractor::copyright() const {
+ DCHECK(extracted_);
+ return copyright_;
+}
+
+const std::string& AudioVideoMetadataExtractor::date() const {
+ DCHECK(extracted_);
+ return date_;
+}
+
+int AudioVideoMetadataExtractor::disc() const {
+ DCHECK(extracted_);
+ return disc_;
+}
+
+const std::string& AudioVideoMetadataExtractor::encoder() const {
+ DCHECK(extracted_);
+ return encoder_;
+}
+
+const std::string& AudioVideoMetadataExtractor::encoded_by() const {
+ DCHECK(extracted_);
+ return encoded_by_;
+}
+
+const std::string& AudioVideoMetadataExtractor::genre() const {
+ DCHECK(extracted_);
+ return genre_;
+}
+
+const std::string& AudioVideoMetadataExtractor::language() const {
+ DCHECK(extracted_);
+ return language_;
+}
+
+const std::string& AudioVideoMetadataExtractor::title() const {
+ DCHECK(extracted_);
+ return title_;
+}
+
+int AudioVideoMetadataExtractor::track() const {
+ DCHECK(extracted_);
+ return track_;
+}
+
+void AudioVideoMetadataExtractor::ExtractDictionary(AVDictionary* metadata) {
+ if (!metadata)
+ return;
+
+ AVDictionaryEntry* tag = NULL;
+ while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ if (ExtractString(tag, "album", &album_)) continue;
+ if (ExtractString(tag, "artist", &artist_)) continue;
+ if (ExtractString(tag, "comment", &comment_)) continue;
+ if (ExtractString(tag, "copyright", &copyright_)) continue;
+ if (ExtractString(tag, "date", &date_)) continue;
+ if (ExtractInt(tag, "disc", &disc_)) continue;
+ if (ExtractString(tag, "encoder", &encoder_)) continue;
+ if (ExtractString(tag, "encoded_by", &encoded_by_)) continue;
+ if (ExtractString(tag, "genre", &genre_)) continue;
+ if (ExtractString(tag, "language", &language_)) continue;
+ if (ExtractString(tag, "title", &title_)) continue;
+ if (ExtractInt(tag, "track", &track_)) continue;
+ }
+}
+
+} // namespace media
« no previous file with comments | « media/base/audio_video_metadata_extractor.h ('k') | media/base/audio_video_metadata_extractor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698