15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/audio_video_metadata_extractor.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/filters/blocking_url_protocol.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/filters/ffmpeg_glue.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OnError(bool* succeeded) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *succeeded = false;
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns true if the |tag| matches |expected_key|.
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtractString(AVDictionaryEntry* tag, const char* expected_key,
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   std::string* destination) {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!LowerCaseEqualsASCII(std::string(tag->key), expected_key))
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (destination->empty())
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *destination = tag->value;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns true if the |tag| matches |expected_key|.
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtractInt(AVDictionaryEntry* tag, const char* expected_key,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                int* destination) {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!LowerCaseEqualsASCII(std::string(tag->key), expected_key))
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int temporary = -1;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (*destination < 0 && base::StringToInt(tag->value, &temporary) &&
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      temporary >= 0) {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *destination = temporary;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Set attached image size limit to 4MB. Chosen arbitrarily.
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kAttachedImageSizeLimit = 4 * 1024 * 1024;
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
550529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochAudioVideoMetadataExtractor::StreamInfo::StreamInfo() {}
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
570529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochAudioVideoMetadataExtractor::StreamInfo::~StreamInfo() {}
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AudioVideoMetadataExtractor::AudioVideoMetadataExtractor()
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : extracted_(false),
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      duration_(-1),
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      width_(-1),
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      height_(-1),
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      disc_(-1),
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rotation_(-1),
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      track_(-1) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool AudioVideoMetadataExtractor::Extract(DataSource* source,
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          bool extract_attached_images) {
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!extracted_);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool read_ok = true;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::BlockingUrlProtocol protocol(source, base::Bind(&OnError, &read_ok));
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::FFmpegGlue glue(&protocol);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AVFormatContext* format_context = glue.format_context();
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!glue.OpenContext())
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!read_ok)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!format_context->iformat)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (avformat_find_stream_info(format_context, NULL) < 0)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (format_context->duration != AV_NOPTS_VALUE)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    duration_ = static_cast<double>(format_context->duration) / AV_TIME_BASE;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  stream_infos_.push_back(StreamInfo());
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StreamInfo& container_info = stream_infos_.back();
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  container_info.type = format_context->iformat->name;
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ExtractDictionary(format_context->metadata, &container_info.tags);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (unsigned int i = 0; i < format_context->nb_streams; ++i) {
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    stream_infos_.push_back(StreamInfo());
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    StreamInfo& info = stream_infos_.back();
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AVStream* stream = format_context->streams[i];
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!stream)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Extract dictionary from streams also. Needed for containers that attach
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // metadata to contained streams instead the container itself, like OGG.
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ExtractDictionary(stream->metadata, &info.tags);
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!stream->codec)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    info.type = avcodec_get_name(stream->codec->codec_id);
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Extract dimensions of largest stream that's not an attached image.
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (stream->codec->width > 0 && stream->codec->width > width_ &&
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        stream->codec->height > 0 && stream->codec->height > height_) {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      width_ = stream->codec->width;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      height_ = stream->codec->height;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Extract attached image if requested.
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extract_attached_images &&
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        stream->disposition == AV_DISPOSITION_ATTACHED_PIC &&
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        stream->attached_pic.size > 0 &&
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        stream->attached_pic.size <= kAttachedImageSizeLimit &&
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        stream->attached_pic.data != NULL) {
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      attached_images_bytes_.push_back(std::string());
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      attached_images_bytes_.back().assign(
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          reinterpret_cast<const char*>(stream->attached_pic.data),
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          stream->attached_pic.size);
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extracted_ = true;
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)double AudioVideoMetadataExtractor::duration() const {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return duration_;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AudioVideoMetadataExtractor::width() const {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return width_;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AudioVideoMetadataExtractor::height() const {
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return height_;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AudioVideoMetadataExtractor::rotation() const {
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return rotation_;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::album() const {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return album_;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::artist() const {
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return artist_;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::comment() const {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return comment_;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::copyright() const {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return copyright_;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::date() const {
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return date_;
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AudioVideoMetadataExtractor::disc() const {
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return disc_;
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::encoder() const {
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return encoder_;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::encoded_by() const {
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return encoded_by_;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::genre() const {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return genre_;
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::language() const {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return language_;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& AudioVideoMetadataExtractor::title() const {
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return title_;
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AudioVideoMetadataExtractor::track() const {
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(extracted_);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return track_;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst std::vector<AudioVideoMetadataExtractor::StreamInfo>&
2230529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochAudioVideoMetadataExtractor::stream_infos() const {
224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(extracted_);
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return stream_infos_;
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const std::vector<std::string>&
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AudioVideoMetadataExtractor::attached_images_bytes() const {
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(extracted_);
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return attached_images_bytes_;
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid AudioVideoMetadataExtractor::ExtractDictionary(
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AVDictionary* metadata, TagDictionary* raw_tags) {
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!metadata)
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (AVDictionaryEntry* tag =
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           av_dict_get(metadata, "", NULL, AV_DICT_IGNORE_SUFFIX);
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       tag; tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX)) {
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (raw_tags->find(tag->key) == raw_tags->end())
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      (*raw_tags)[tag->key] = tag->value;
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractInt(tag, "rotate", &rotation_)) continue;
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "album", &album_)) continue;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "artist", &artist_)) continue;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "comment", &comment_)) continue;
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "copyright", &copyright_)) continue;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "date", &date_)) continue;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractInt(tag, "disc", &disc_)) continue;
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "encoder", &encoder_)) continue;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "encoded_by", &encoded_by_)) continue;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "genre", &genre_)) continue;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "language", &language_)) continue;
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractString(tag, "title", &title_)) continue;
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ExtractInt(tag, "track", &track_)) continue;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
262