// 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_mpeg1audio.h"

#include <vector>

#include "base/bind.h"
#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/mpeg1_audio_stream_parser.h"

namespace cobalt {
namespace media {
namespace mp2t {

struct EsParserMpeg1Audio::Mpeg1AudioFrame {
  // Pointer to the ES data.
  const uint8_t* data;

  // Frame size.
  int size;

  // Number of samples in the frame.
  int sample_count;

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

EsParserMpeg1Audio::EsParserMpeg1Audio(
    const NewAudioConfigCB& new_audio_config_cb,
    const EmitBufferCB& emit_buffer_cb,
    const scoped_refptr<MediaLog>& media_log)
    : media_log_(media_log),
      new_audio_config_cb_(new_audio_config_cb),
      emit_buffer_cb_(emit_buffer_cb) {}

EsParserMpeg1Audio::~EsParserMpeg1Audio() {}

bool EsParserMpeg1Audio::ParseFromEsQueue() {
  // Look for every MPEG1 audio frame in the ES buffer.
  Mpeg1AudioFrame mpeg1audio_frame;
  while (LookForMpeg1AudioFrame(&mpeg1audio_frame)) {
    // Update the audio configuration if needed.
    DCHECK_GE(mpeg1audio_frame.size, MPEG1AudioStreamParser::kHeaderSize);
    if (!UpdateAudioConfiguration(mpeg1audio_frame.data)) return false;

    // Get the PTS & the duration of this access unit.
    TimingDesc current_timing_desc =
        GetTimingDescriptor(mpeg1audio_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";
      SkipMpeg1AudioFrame(mpeg1audio_frame);
      continue;
    }
    base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp();
    base::TimeDelta frame_duration = audio_timestamp_helper_->GetFrameDuration(
        mpeg1audio_frame.sample_count);

    // 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(mpeg1audio_frame.data,
                                     mpeg1audio_frame.size, is_key_frame,
                                     DemuxerStream::AUDIO, kMp2tAudioTrackId);
    if (!stream_parser_buffer) {
      return false;
    }
    stream_parser_buffer->set_timestamp(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(mpeg1audio_frame.sample_count);

    // Skip the current frame.
    SkipMpeg1AudioFrame(mpeg1audio_frame);
  }

  return true;
}

void EsParserMpeg1Audio::Flush() {}

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

bool EsParserMpeg1Audio::LookForMpeg1AudioFrame(
    Mpeg1AudioFrame* mpeg1audio_frame) {
  int es_size;
  const uint8_t* es;
  es_queue_->Peek(&es, &es_size);

  int max_offset = es_size - MPEG1AudioStreamParser::kHeaderSize;
  if (max_offset <= 0) return false;

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

    int remaining_size = es_size - offset;
    DCHECK_GE(remaining_size, MPEG1AudioStreamParser::kHeaderSize);
    MPEG1AudioStreamParser::Header header;
    if (!MPEG1AudioStreamParser::ParseHeader(media_log_, cur_buf, &header))
      continue;

    if (remaining_size < header.frame_size) {
      // Not a full frame: will resume when we have more data.
      // Remove all the bytes located before the frame header,
      // these bytes will not be used anymore.
      es_queue_->Pop(offset);
      return false;
    }

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

    es_queue_->Pop(offset);
    es_queue_->Peek(&mpeg1audio_frame->data, &es_size);
    mpeg1audio_frame->queue_offset = es_queue_->head();
    mpeg1audio_frame->size = header.frame_size;
    mpeg1audio_frame->sample_count = header.sample_count;
    DVLOG(LOG_LEVEL_ES) << "MPEG1 audio syncword @ pos="
                        << mpeg1audio_frame->queue_offset
                        << " frame_size=" << mpeg1audio_frame->size;
    DVLOG(LOG_LEVEL_ES) << "MPEG1 audio header: "
                        << base::HexEncode(mpeg1audio_frame->data,
                                           MPEG1AudioStreamParser::kHeaderSize);
    return true;
  }

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

bool EsParserMpeg1Audio::UpdateAudioConfiguration(
    const uint8_t* mpeg1audio_header) {
  MPEG1AudioStreamParser::Header header;
  if (!MPEG1AudioStreamParser::ParseHeader(media_log_, mpeg1audio_header,
                                           &header)) {
    return false;
  }

  // TODO(damienv): Verify whether Android playback requires the extra data
  // field for Mpeg1 audio. If yes, we should generate this field.
  AudioDecoderConfig audio_decoder_config(
      kCodecMP3, kSampleFormatS16, header.channel_layout, header.sample_rate,
      EmptyExtraData(), Unencrypted());

  if (!audio_decoder_config.Matches(last_audio_decoder_config_)) {
    DVLOG(1) << "Sampling frequency: " << header.sample_rate;
    DVLOG(1) << "Channel layout: " << header.channel_layout;
    // 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(header.sample_rate));
      audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
    } else {
      audio_timestamp_helper_.reset(
          new AudioTimestampHelper(header.sample_rate));
    }
    // Audio config notification.
    last_audio_decoder_config_ = audio_decoder_config;
    new_audio_config_cb_.Run(audio_decoder_config);
  }

  return true;
}

void EsParserMpeg1Audio::SkipMpeg1AudioFrame(
    const Mpeg1AudioFrame& mpeg1audio_frame) {
  DCHECK_EQ(mpeg1audio_frame.queue_offset, es_queue_->head());
  es_queue_->Pop(mpeg1audio_frame.size);
}

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