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

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: refine metadata extraction logic 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 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.
4
5 #include "media/base/audio_video_metadata_extractor.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/strings/string_util.h"
11 #include "base/time/time.h"
12 #include "media/ffmpeg/ffmpeg_common.h"
13 #include "media/filters/blocking_url_protocol.h"
14 #include "media/filters/ffmpeg_glue.h"
15
16 namespace media {
17
18 namespace {
19
20 static void OnError(bool* called) {
21 *called = false;
22 }
23
24 std::map<std::string, std::string> ExtractAVMetadata(AVDictionary* metadata) {
25 DCHECK(metadata);
26
27 std::map<std::string, std::string> tags;
28
29 AVDictionaryEntry *tag = NULL;
30 while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
31 std::string key = tag->key;
32 StringToLowerASCII(&key);
33 tags[key] = std::string(tag->value);
34 }
35
36 return tags;
37 }
38
39 } // namespace
40
41 AudioVideoMetadataExtractor::AudioVideoMetadataExtractor(DataSource* source)
42 : source_(source),
43 extracted_(false),
44 duration_(-1),
45 width_(0),
46 height_(0) {
47 }
48
49 AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
50 }
51
52 bool AudioVideoMetadataExtractor::Extract() {
53 bool read_ok = true;
54 media::BlockingUrlProtocol protocol(source_, base::Bind(&OnError, &read_ok));
55 media::FFmpegGlue glue(&protocol);
56 AVFormatContext* format_context = glue.format_context();
57
58 if (!glue.OpenContext())
59 return false;
60
61 if (!read_ok)
62 return false;
63
64 if (!format_context->iformat)
65 return false;
66
67 if (avformat_find_stream_info(format_context, NULL) < 0)
68 return false;
69
70 format_ = format_context->iformat->name;
71
72 if (format_context->duration != AV_NOPTS_VALUE)
73 duration_ = format_context->duration / AV_TIME_BASE;
74
75 if (format_context->metadata)
76 tags_ = ExtractAVMetadata(format_context->metadata);
77
78 bool container_has_metadata = !tags_.empty();
79
80 for (unsigned int i = 0; i < format_context->nb_streams; ++i) {
81 AVStream* stream = format_context->streams[i];
82 if (!stream)
83 continue;
84
85 // Ignore attached pictures for metadata extraction.
86 if ((stream->disposition & AV_DISPOSITION_ATTACHED_PIC) != 0)
87 continue;
88
89 // If the container does not have metadata, take the metadata from the
90 // stream with the most tags. This is needed for containers that attach
91 // 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.
92 if (!container_has_metadata && stream->metadata) {
93 std::map<std::string, std::string> stream_tags =
94 ExtractAVMetadata(stream->metadata);
95 if (stream_tags.size() > tags_.size())
96 tags_ = stream_tags;
97 }
98
99 if (!stream->codec)
100 continue;
101
102 // Extract dimensions of largest stream that's not an attached picture.
103 if (stream->codec->width > width_ && stream->codec->height > height_) {
104 width_ = stream->codec->width;
105 height_ = stream->codec->height;
106 }
107 }
108
109 extracted_ = true;
110 return true;
111 }
112
113 const std::map<std::string, std::string>&
114 AudioVideoMetadataExtractor::GetTags() {
115 DCHECK(extracted_);
116 return tags_;
117 }
118
119 const std::string& AudioVideoMetadataExtractor::GetFormat() {
120 DCHECK(extracted_);
121 return format_;
122 }
123
124 int AudioVideoMetadataExtractor::GetDurationSeconds() {
125 DCHECK(extracted_);
126 return duration_;
127 }
128
129 int AudioVideoMetadataExtractor::GetWidth() {
130 DCHECK(extracted_);
131 return width_;
132 }
133
134 int AudioVideoMetadataExtractor::GetHeight() {
135 DCHECK(extracted_);
136 return height_;
137 }
138
139 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698