// 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 "cobalt/media/base/audio_video_metadata_extractor.h"

#include "base/bind.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/time.h"
#include "cobalt/media/ffmpeg/ffmpeg_common.h"
#include "cobalt/media/filters/blocking_url_protocol.h"
#include "cobalt/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 (!base::LowerCaseEqualsASCII(std::string(tag->key), expected_key))
    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 (!base::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;
}

// Set attached image size limit to 4MB. Chosen arbitrarily.
const int kAttachedImageSizeLimit = 4 * 1024 * 1024;

}  // namespace

AudioVideoMetadataExtractor::StreamInfo::StreamInfo() {}

AudioVideoMetadataExtractor::StreamInfo::StreamInfo(const StreamInfo& other) =
    default;

AudioVideoMetadataExtractor::StreamInfo::~StreamInfo() {}

AudioVideoMetadataExtractor::AudioVideoMetadataExtractor()
    : extracted_(false),
      duration_(-1),
      width_(-1),
      height_(-1),
      disc_(-1),
      rotation_(-1),
      track_(-1) {}

AudioVideoMetadataExtractor::~AudioVideoMetadataExtractor() {}

bool AudioVideoMetadataExtractor::Extract(DataSource* source,
                                          bool extract_attached_images) {
  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;

  stream_infos_.push_back(StreamInfo());
  StreamInfo& container_info = stream_infos_.back();
  container_info.type = format_context->iformat->name;
  ExtractDictionary(format_context->metadata, &container_info.tags);

  for (unsigned int i = 0; i < format_context->nb_streams; ++i) {
    stream_infos_.push_back(StreamInfo());
    StreamInfo& info = stream_infos_.back();

    AVStream* stream = format_context->streams[i];
    if (!stream) continue;

    // Extract dictionary from streams also. Needed for containers that attach
    // metadata to contained streams instead the container itself, like OGG.
    ExtractDictionary(stream->metadata, &info.tags);

    if (!stream->codec) continue;

    info.type = avcodec_get_name(stream->codec->codec_id);

    // 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;
  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_;
}

int AudioVideoMetadataExtractor::rotation() const {
  DCHECK(extracted_);
  return rotation_;
}

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_;
}

const std::vector<AudioVideoMetadataExtractor::StreamInfo>&
AudioVideoMetadataExtractor::stream_infos() const {
  DCHECK(extracted_);
  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) return;

  for (AVDictionaryEntry* tag =
           av_dict_get(metadata, "", NULL, AV_DICT_IGNORE_SUFFIX);
       tag; tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX)) {
    if (raw_tags->find(tag->key) == raw_tags->end())
      (*raw_tags)[tag->key] = tag->value;

    if (ExtractInt(tag, "rotate", &rotation_)) continue;
    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
