// 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);
    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
