// 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/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/time/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 cobalt {
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
}  // namespace cobalt
