Commit e677dfa5 authored by tommycli@chromium.org's avatar tommycli@chromium.org

Media: Add thumbnail extraction to AudioVideoMetadataExtractor.

Spinoff of patch https://codereview.chromium.org/250143002/

For trivial change in chrome/utility/media_galleries/media_metadata_parser.cc:
TBR=vandebo

BUG=304290

Review URL: https://codereview.chromium.org/270873003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269588 0039d316-1c4b-4281-b951-d872f2087c98
parent 8c3b86ea
......@@ -56,7 +56,8 @@ scoped_ptr<MediaMetadataParser::MediaMetadata> ParseAudioVideoMetadata(
DCHECK(metadata.get());
media::AudioVideoMetadataExtractor extractor;
if (!extractor.Extract(source))
// TODO(tommycli): Add attached picture extraction.
if (!extractor.Extract(source, false /* extract_attached_pics */))
return metadata.Pass();
if (extractor.duration() >= 0)
......
......@@ -47,6 +47,9 @@ bool ExtractInt(AVDictionaryEntry* tag, const char* expected_key,
return true;
}
// Set attached image size limit to 4MB. Chosen arbitrarily.
const int kAttachedImageSizeLimit = 4 * 1024 * 1024;
} // namespace
AudioVideoMetadataExtractor::StreamInfo::StreamInfo() {}
......@@ -66,7 +69,8 @@ AudioVideoMetadataExtractor::AudioVideoMetadataExtractor()
AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
}
bool AudioVideoMetadataExtractor::Extract(DataSource* source) {
bool AudioVideoMetadataExtractor::Extract(DataSource* source,
bool extract_attached_images) {
DCHECK(!extracted_);
bool read_ok = true;
......@@ -111,12 +115,24 @@ bool AudioVideoMetadataExtractor::Extract(DataSource* source) {
info.type = avcodec_get_name(stream->codec->codec_id);
// Extract dimensions of largest stream that's not an attached picture.
// Extract dimensions of largest stream that's not an attached image.
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;
}
// Extract attached image if requested.
if (extract_attached_images &&
stream->disposition == AV_DISPOSITION_ATTACHED_PIC &&
stream->attached_pic.size > 0 &&
stream->attached_pic.size <= kAttachedImageSizeLimit &&
stream->attached_pic.data != NULL) {
attached_images_bytes_.push_back(std::string());
attached_images_bytes_.back().assign(
reinterpret_cast<const char*>(stream->attached_pic.data),
stream->attached_pic.size);
}
}
extracted_ = true;
......@@ -209,6 +225,12 @@ AudioVideoMetadataExtractor::stream_infos() const {
return stream_infos_;
}
const std::vector<std::string>&
AudioVideoMetadataExtractor::attached_images_bytes() const {
DCHECK(extracted_);
return attached_images_bytes_;
}
void AudioVideoMetadataExtractor::ExtractDictionary(
AVDictionary* metadata, TagDictionary* raw_tags) {
if (!metadata)
......
......@@ -38,7 +38,7 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
// Returns whether or not the fields were successfully extracted. Should only
// be called once.
bool Extract(DataSource* source);
bool Extract(DataSource* source, bool extract_attached_pics);
// Returns -1 if we cannot extract the duration. In seconds.
double duration() const;
......@@ -67,6 +67,10 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
// First element is the container. Subsequent elements are the child streams.
const StreamInfoVector& stream_infos() const;
// Empty if Extract call did not request attached images, or if no attached
// images were found.
const std::vector<std::string>& attached_images_bytes() const;
private:
void ExtractDictionary(AVDictionary* metadata, TagDictionary* raw_tags);
......@@ -92,6 +96,8 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
StreamInfoVector stream_infos_;
std::vector<std::string> attached_images_bytes_;
DISALLOW_COPY_AND_ASSIGN(AudioVideoMetadataExtractor);
};
......
......@@ -4,6 +4,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/sha1.h"
#include "build/build_config.h"
#include "media/base/audio_video_metadata_extractor.h"
#include "media/base/test_data_util.h"
......@@ -14,6 +15,7 @@ namespace media {
scoped_ptr<AudioVideoMetadataExtractor> GetExtractor(
const std::string& filename,
bool extract_attached_images,
bool expected_result,
double expected_duration,
int expected_width,
......@@ -23,7 +25,7 @@ scoped_ptr<AudioVideoMetadataExtractor> GetExtractor(
scoped_ptr<AudioVideoMetadataExtractor> extractor(
new AudioVideoMetadataExtractor);
bool extracted = extractor->Extract(&source);
bool extracted = extractor->Extract(&source, extract_attached_images);
EXPECT_EQ(expected_result, extracted);
if (!extracted)
......@@ -38,12 +40,12 @@ scoped_ptr<AudioVideoMetadataExtractor> GetExtractor(
}
TEST(AudioVideoMetadataExtractorTest, InvalidFile) {
GetExtractor("ten_byte_file", false, 0, -1, -1);
GetExtractor("ten_byte_file", true, false, 0, -1, -1);
}
TEST(AudioVideoMetadataExtractorTest, AudioOGG) {
scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("9ch.ogg", true, 0, -1, -1);
GetExtractor("9ch.ogg", true, true, 0, -1, -1);
EXPECT_EQ("Processed by SoX", extractor->comment());
EXPECT_EQ("ogg", extractor->stream_infos()[0].type);
......@@ -55,11 +57,13 @@ TEST(AudioVideoMetadataExtractorTest, AudioOGG) {
EXPECT_EQ("vorbis", extractor->stream_infos()[1].type);
EXPECT_EQ("Processed by SoX",
extractor->stream_infos()[1].tags.find("COMMENT")->second);
EXPECT_EQ(0u, extractor->attached_images_bytes().size());
}
TEST(AudioVideoMetadataExtractorTest, AudioWAV) {
scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("sfx_u8.wav", true, 0, -1, -1);
GetExtractor("sfx_u8.wav", true, true, 0, -1, -1);
EXPECT_EQ("Lavf54.37.100", extractor->encoder());
EXPECT_EQ("Amadeus Pro", extractor->encoded_by());
......@@ -74,11 +78,13 @@ TEST(AudioVideoMetadataExtractorTest, AudioWAV) {
EXPECT_EQ("pcm_u8", extractor->stream_infos()[1].type);
EXPECT_EQ(0u, extractor->stream_infos()[1].tags.size());
EXPECT_EQ(0u, extractor->attached_images_bytes().size());
}
TEST(AudioVideoMetadataExtractorTest, VideoWebM) {
scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("bear-320x240-multitrack.webm", true, 2, 320, 240);
GetExtractor("bear-320x240-multitrack.webm", true, true, 2, 320, 240);
EXPECT_EQ("Lavf53.9.0", extractor->encoder());
EXPECT_EQ(6u, extractor->stream_infos().size());
......@@ -104,12 +110,14 @@ TEST(AudioVideoMetadataExtractorTest, VideoWebM) {
EXPECT_EQ(1u, extractor->stream_infos()[5].tags.size());
EXPECT_EQ("Lavc52.32.0",
extractor->stream_infos()[5].tags.find("ENCODER")->second);
EXPECT_EQ(0u, extractor->attached_images_bytes().size());
}
#if defined(USE_PROPRIETARY_CODECS)
TEST(AudioVideoMetadataExtractorTest, AndroidRotatedMP4Video) {
scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("90rotation.mp4", true, 0, 1920, 1080);
GetExtractor("90rotation.mp4", true, true, 0, 1920, 1080);
EXPECT_EQ(90, extractor->rotation());
......@@ -144,11 +152,13 @@ TEST(AudioVideoMetadataExtractorTest, AndroidRotatedMP4Video) {
EXPECT_EQ("SoundHandle",
extractor->stream_infos()[2].tags.find("handler_name")->second);
EXPECT_EQ("eng", extractor->stream_infos()[2].tags.find("language")->second);
EXPECT_EQ(0u, extractor->attached_images_bytes().size());
}
TEST(AudioVideoMetadataExtractorTest, AudioMP3) {
scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("id3_png_test.mp3", true, 1, -1, -1);
GetExtractor("id3_png_test.mp3", true, true, 1, -1, -1);
EXPECT_EQ("Airbag", extractor->title());
EXPECT_EQ("Radiohead", extractor->artist());
......@@ -181,6 +191,17 @@ TEST(AudioVideoMetadataExtractorTest, AudioMP3) {
EXPECT_EQ(2u, extractor->stream_infos()[2].tags.size());
EXPECT_EQ("Other", extractor->stream_infos()[2].tags.find("comment")->second);
EXPECT_EQ("", extractor->stream_infos()[2].tags.find("title")->second);
EXPECT_EQ(1u, extractor->attached_images_bytes().size());
EXPECT_EQ(155752u, extractor->attached_images_bytes()[0].size());
EXPECT_EQ("\x89PNG\r\n\x1a\n",
extractor->attached_images_bytes()[0].substr(0, 8));
EXPECT_EQ("IEND\xae\x42\x60\x82",
extractor->attached_images_bytes()[0].substr(
extractor->attached_images_bytes()[0].size() - 8, 8));
EXPECT_EQ("\xF3\xED\x8F\xC7\xC7\x98\xB9V|p\xC0u!\xB5\x82\xCF\x95\xF0\xCD\xCE",
base::SHA1HashString(extractor->attached_images_bytes()[0]));
}
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment