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

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: refine metadata extraction logic Created 6 years, 12 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
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..268a5e157aa538b2916f7e35ce725d77650b86ec
--- /dev/null
+++ b/media/base/audio_video_metadata_extractor.cc
@@ -0,0 +1,139 @@
+// Copyright 2013 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 <map>
+
+#include "base/bind.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 {
+
+static void OnError(bool* called) {
+ *called = false;
+}
+
+std::map<std::string, std::string> ExtractAVMetadata(AVDictionary* metadata) {
+ DCHECK(metadata);
+
+ std::map<std::string, std::string> tags;
+
+ AVDictionaryEntry *tag = NULL;
+ while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ std::string key = tag->key;
+ StringToLowerASCII(&key);
+ tags[key] = std::string(tag->value);
+ }
+
+ return tags;
+}
+
+} // namespace
+
+AudioVideoMetadataExtractor::AudioVideoMetadataExtractor(DataSource* source)
+ : source_(source),
+ extracted_(false),
+ duration_(-1),
+ width_(0),
+ height_(0) {
+}
+
+AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
+}
+
+bool AudioVideoMetadataExtractor::Extract() {
+ 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;
+
+ format_ = format_context->iformat->name;
+
+ if (format_context->duration != AV_NOPTS_VALUE)
+ duration_ = format_context->duration / AV_TIME_BASE;
+
+ if (format_context->metadata)
+ tags_ = ExtractAVMetadata(format_context->metadata);
+
+ bool container_has_metadata = !tags_.empty();
+
+ 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;
+
+ // If the container does not have metadata, take the metadata from the
+ // stream with the most tags. This is needed for containers that attach
+ // metadata to contained streams instead the container itself, like OGG.
acolwell GONE FROM CHROMIUM 2014/01/03 19:14:04 This seems brittle. How about just taking the firs
tommycli 2014/01/03 23:08:36 Done.
+ if (!container_has_metadata && stream->metadata) {
+ std::map<std::string, std::string> stream_tags =
+ ExtractAVMetadata(stream->metadata);
+ if (stream_tags.size() > tags_.size())
+ tags_ = stream_tags;
+ }
+
+ if (!stream->codec)
+ continue;
+
+ // Extract dimensions of largest stream that's not an attached picture.
+ if (stream->codec->width > width_ && stream->codec->height > height_) {
+ width_ = stream->codec->width;
+ height_ = stream->codec->height;
+ }
+ }
+
+ extracted_ = true;
+ return true;
+}
+
+const std::map<std::string, std::string>&
+AudioVideoMetadataExtractor::GetTags() {
+ DCHECK(extracted_);
+ return tags_;
+}
+
+const std::string& AudioVideoMetadataExtractor::GetFormat() {
+ DCHECK(extracted_);
+ return format_;
+}
+
+int AudioVideoMetadataExtractor::GetDurationSeconds() {
+ DCHECK(extracted_);
+ return duration_;
+}
+
+int AudioVideoMetadataExtractor::GetWidth() {
+ DCHECK(extracted_);
+ return width_;
+}
+
+int AudioVideoMetadataExtractor::GetHeight() {
+ DCHECK(extracted_);
+ return height_;
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698