// 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 "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 "media/base/audio_timestamp_helper.h"
#include "media/base/bit_reader.h"
#include "media/base/channel_layout.h"
#include "media/base/media_util.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/timestamp_constants.h"
#include "media/formats/common/offset_byte_queue.h"
#include "media/formats/mp2t/mp2t_common.h"
#include "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);
    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
