// 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/formats/mp2t/es_parser_adts.h"

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "cobalt/media/base/audio_timestamp_helper.h"
#include "cobalt/media/base/bit_reader.h"
#include "cobalt/media/base/channel_layout.h"
#include "cobalt/media/base/media_util.h"
#include "cobalt/media/base/stream_parser_buffer.h"
#include "cobalt/media/base/timestamp_constants.h"
#include "cobalt/media/formats/common/offset_byte_queue.h"
#include "cobalt/media/formats/mp2t/mp2t_common.h"
#include "cobalt/media/formats/mpeg/adts_constants.h"
#include "starboard/types.h"

namespace cobalt {
namespace media {

static int ExtractAdtsFrameSize(const uint8_t* adts_header) {
  return ((static_cast<int>(adts_header[5]) >> 5) |
          (static_cast<int>(adts_header[4]) << 3) |
          ((static_cast<int>(adts_header[3]) & 0x3) << 11));
}

// Return true if buf corresponds to an ADTS syncword.
// |buf| size must be at least 2.
static bool isAdtsSyncWord(const uint8_t* buf) {
  // The first 12 bits must be 1.
  // The layer field (2 bits) must be set to 0.
  return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
}

namespace mp2t {

struct EsParserAdts::AdtsFrame {
  // Pointer to the ES data.
  const uint8_t* data;

  // Frame size;
  int size;

  // Frame offset in the ES queue.
  int64_t queue_offset;
};

bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) {
  int es_size;
  const uint8_t* es;
  es_queue_->Peek(&es, &es_size);

  int max_offset = es_size - kADTSHeaderMinSize;
  if (max_offset <= 0) return false;

  for (int offset = 0; offset < max_offset; offset++) {
    const uint8_t* cur_buf = &es[offset];
    if (!isAdtsSyncWord(cur_buf)) continue;

    int frame_size = ExtractAdtsFrameSize(cur_buf);
    if (frame_size < kADTSHeaderMinSize) {
      // Too short to be an ADTS frame.
      continue;
    }

    int remaining_size = es_size - offset;
    if (remaining_size < frame_size) {
      // Not a full frame: will resume when we have more data.
      es_queue_->Pop(offset);
      return false;
    }

    // Check whether there is another frame
    // |size| apart from the current one.
    if (remaining_size >= frame_size + 2 &&
        !isAdtsSyncWord(&cur_buf[frame_size])) {
      continue;
    }

    es_queue_->Pop(offset);
    es_queue_->Peek(&adts_frame->data, &es_size);
    adts_frame->queue_offset = es_queue_->head();
    adts_frame->size = frame_size;
    DVLOG(LOG_LEVEL_ES) << "ADTS syncword @ pos=" << adts_frame->queue_offset
                        << " frame_size=" << adts_frame->size;
    DVLOG(LOG_LEVEL_ES) << "ADTS header: "
                        << base::HexEncode(adts_frame->data,
                                           kADTSHeaderMinSize);
    return true;
  }

  es_queue_->Pop(max_offset);
  return false;
}

void EsParserAdts::SkipAdtsFrame(const AdtsFrame& adts_frame) {
  DCHECK_EQ(adts_frame.queue_offset, es_queue_->head());
  es_queue_->Pop(adts_frame.size);
}

EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb,
                           const EmitBufferCB& emit_buffer_cb,
                           bool sbr_in_mimetype)
    : new_audio_config_cb_(new_audio_config_cb),
      emit_buffer_cb_(emit_buffer_cb),
      sbr_in_mimetype_(sbr_in_mimetype) {}

EsParserAdts::~EsParserAdts() {}

bool EsParserAdts::ParseFromEsQueue() {
  // Look for every ADTS frame in the ES buffer.
  AdtsFrame adts_frame;
  while (LookForAdtsFrame(&adts_frame)) {
    // Update the audio configuration if needed.
    DCHECK_GE(adts_frame.size, kADTSHeaderMinSize);
    if (!UpdateAudioConfiguration(adts_frame.data, adts_frame.size))
      return false;

    // Get the PTS & the duration of this access unit.
    TimingDesc current_timing_desc =
        GetTimingDescriptor(adts_frame.queue_offset);
    if (current_timing_desc.pts != kNoTimestamp)
      audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts);

    if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp) {
      DVLOG(1) << "Skipping audio frame with unknown timestamp";
      SkipAdtsFrame(adts_frame);
      continue;
    }
    base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp();
    base::TimeDelta frame_duration =
        audio_timestamp_helper_->GetFrameDuration(kSamplesPerAACFrame);

    // Emit an audio frame.
    bool is_key_frame = true;

    // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId
    // type and allow multiple audio tracks. See https://crbug.com/341581.
    scoped_refptr<StreamParserBuffer> stream_parser_buffer =
        StreamParserBuffer::CopyFrom(adts_frame.data, adts_frame.size,
                                     is_key_frame, DemuxerStream::AUDIO,
                                     kMp2tAudioTrackId);
    if (!stream_parser_buffer) {
      return false;
    }
    stream_parser_buffer->set_timestamp(current_pts);
    stream_parser_buffer->SetDecodeTimestamp(
        DecodeTimestamp::FromPresentationTime(current_pts));
    stream_parser_buffer->set_duration(frame_duration);
    emit_buffer_cb_.Run(stream_parser_buffer);

    // Update the PTS of the next frame.
    audio_timestamp_helper_->AddFrames(kSamplesPerAACFrame);

    // Skip the current frame.
    SkipAdtsFrame(adts_frame);
  }

  return true;
}

void EsParserAdts::Flush() {}

void EsParserAdts::ResetInternal() {
  last_audio_decoder_config_ = AudioDecoderConfig();
}

bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_header,
                                            int size) {
  int orig_sample_rate;
  ChannelLayout channel_layout;
  std::vector<uint8_t> extra_data;
  if (adts_parser_.ParseFrameHeader(adts_header, size, nullptr,
                                    &orig_sample_rate, &channel_layout, nullptr,
                                    nullptr, &extra_data) <= 0) {
    return false;
  }

  // The following code is written according to ISO 14496 Part 3 Table 1.11 and
  // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
  // to SBR doubling the AAC sample rate.)
  // TODO(damienv) : Extend sample rate cap to 96kHz for Level 5 content.
  const int extended_samples_per_second =
      sbr_in_mimetype_ ? std::min(2 * orig_sample_rate, 48000)
                       : orig_sample_rate;

  AudioDecoderConfig audio_decoder_config(
      kCodecAAC, kSampleFormatS16, channel_layout, extended_samples_per_second,
      extra_data, Unencrypted());

  if (!audio_decoder_config.Matches(last_audio_decoder_config_)) {
    DVLOG(1) << "Sampling frequency: "
             << audio_decoder_config.samples_per_second()
             << " SBR=" << sbr_in_mimetype_;
    DVLOG(1) << "Channel layout: "
             << ChannelLayoutToString(audio_decoder_config.channel_layout());

    // For AAC audio with SBR (Spectral Band Replication) the sampling rate is
    // doubled above, but AudioTimestampHelper should still use the original
    // sample rate to compute audio timestamps and durations correctly.

    // Reset the timestamp helper to use a new time scale.
    if (audio_timestamp_helper_ &&
        audio_timestamp_helper_->base_timestamp() != kNoTimestamp) {
      base::TimeDelta base_timestamp = audio_timestamp_helper_->GetTimestamp();
      audio_timestamp_helper_.reset(new AudioTimestampHelper(orig_sample_rate));
      audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
    } else {
      audio_timestamp_helper_.reset(new AudioTimestampHelper(orig_sample_rate));
    }
    // Audio config notification.
    last_audio_decoder_config_ = audio_decoder_config;
    new_audio_config_cb_.Run(audio_decoder_config);
  }

  return true;
}

}  // namespace mp2t
}  // namespace media
}  // namespace cobalt
