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

#include "base/logging.h"
#include "media/ffmpeg/ffmpeg_common.h"

namespace media {

namespace {

// Creates an ADTS header and stores in |hdr|
// Assumes |hdr| points to an array of length |kAdtsHeaderSize|
// Returns false if parameter values are for an unsupported configuration.
bool GenerateAdtsHeader(int codec,
                        int layer,
                        int audio_profile,
                        int sample_rate_index,
                        int private_stream,
                        int channel_configuration,
                        int originality,
                        int home,
                        int copyrighted_stream,
                        int copyright_start,
                        int frame_length,
                        int buffer_fullness,
                        int number_of_frames_minus_one,
                        uint8_t* hdr) {
  DCHECK_EQ(codec, AV_CODEC_ID_AAC);

  memset(reinterpret_cast<void *>(hdr), 0,
         FFmpegAACBitstreamConverter::kAdtsHeaderSize);
  // Ref: http://wiki.multimedia.cx/index.php?title=ADTS
  // ADTS header structure is the following
  // AAAAAAAA  AAAABCCD  EEFFFFGH  HHIJKLMM  MMMMMMMM  MMMOOOOO  OOOOOOPP
  //
  // A    Syncword 0xFFF, all bits must be 1
  // B    MPEG Version: 0 for MPEG-4, 1 for MPEG-2
  // C    Layer: always 0
  // D    Protection absent: Set to 1 if no CRC and 0 if there is CRC.
  // E    Profile: the MPEG-4 Audio Object Type minus 1.
  // F    MPEG-4 Sampling Frequency Index (15 is forbidden)
  // G    Private stream:
  // H    MPEG-4 Channel Configuration
  // I    Originality
  // J    Home
  // K    Copyrighted Stream
  // L    Copyright_ start
  // M    Frame length. This must include the ADTS header length.
  // O    Buffer fullness
  // P    Number of AAC frames in ADTS frame minus 1.
  //      For maximum compatibility always use 1 AAC frame per ADTS frame.

  // Syncword
  hdr[0] = 0xFF;
  hdr[1] = 0xF0;

  // Layer is always 0. No further action required.

  // Protection absent (no CRC) is always 1.
  hdr[1] |= 1;

  switch (audio_profile) {
    case FF_PROFILE_AAC_MAIN:
      break;
    case FF_PROFILE_AAC_HE:
    case FF_PROFILE_AAC_HE_V2:
    case FF_PROFILE_AAC_LOW:
      hdr[2] |= (1 << 6);
      break;
    case FF_PROFILE_AAC_SSR:
      hdr[2] |= (2 << 6);
      break;
    case FF_PROFILE_AAC_LTP:
      hdr[2] |= (3 << 6);
      break;
    default:
      DLOG(ERROR) << "[" << __func__ << "] "
                  << "unsupported audio profile:" << audio_profile;
      return false;
  }

  hdr[2] |= ((sample_rate_index & 0xf) << 2);

  if (private_stream)
    hdr[2] |= (1 << 1);

  switch (channel_configuration) {
    case 1:
      // front-center
      hdr[3] |= (1 << 6);
      break;
    case 2:
      // front-left, front-right
      hdr[3] |= (2 << 6);
      break;
    case 3:
      // front-center, front-left, front-right
      hdr[3] |= (3 << 6);
      break;
    case 4:
      // front-center, front-left, front-right, back-center
      hdr[2] |= 1;
      break;
    case 5:
      // front-center, front-left, front-right, back-left, back-right
      hdr[2] |= 1;
      hdr[3] |= (1 << 6);
      break;
    case 6:
      // front-center, front-left, front-right, back-left, back-right,
      // LFE-channel
      hdr[2] |= 1;
      hdr[3] |= (2 << 6);
      break;
    case 8:
      // front-center, front-left, front-right, side-left, side-right,
      // back-left, back-right, LFE-channel
      hdr[2] |= 1;
      hdr[3] |= (3 << 6);
      break;
    default:
      DLOG(ERROR) << "[" << __func__ << "] "
                  << "unsupported number of audio channels:"
                  << channel_configuration;
      return false;
  }

  if (originality)
    hdr[3] |= (1 << 5);

  if (home)
    hdr[3] |= (1 << 4);

  if (copyrighted_stream)
    hdr[3] |= (1 << 3);

  if (copyright_start)
    hdr[3] |= (1 << 2);

  // frame length
  hdr[3] |= (frame_length >> 11) & 0x03;
  hdr[4] = (frame_length >> 3) & 0xFF;
  hdr[5] |= (frame_length & 7) << 5;

  // buffer fullness
  hdr[5] |= (buffer_fullness >> 6) & 0x1F;
  hdr[6] |= (buffer_fullness & 0x3F) << 2;

  hdr[6] |= number_of_frames_minus_one & 0x3;

  return true;
}

}

FFmpegAACBitstreamConverter::FFmpegAACBitstreamConverter(
    AVCodecParameters* stream_codec_parameters)
    : stream_codec_parameters_(stream_codec_parameters),
      header_generated_(false),
      codec_(),
      audio_profile_(),
      sample_rate_index_(),
      channel_configuration_(),
      frame_length_() {
  CHECK(stream_codec_parameters_);
}

FFmpegAACBitstreamConverter::~FFmpegAACBitstreamConverter() {
}

bool FFmpegAACBitstreamConverter::ConvertPacket(AVPacket* packet) {
  if (packet == NULL || !packet->data) {
    return false;
  }

  int header_plus_packet_size =
      packet->size + kAdtsHeaderSize;
  if (!stream_codec_parameters_->extradata) {
    DLOG(ERROR) << "extradata is null";
    return false;
  }
  if (stream_codec_parameters_->extradata_size < 2) {
    DLOG(ERROR) << "extradata too small to contain MP4A header";
    return false;
  }
  int sample_rate_index =
      ((stream_codec_parameters_->extradata[0] & 0x07) << 1) |
      ((stream_codec_parameters_->extradata[1] & 0x80) >> 7);
  if (sample_rate_index > 12) {
    sample_rate_index = 4;
  }

  if (!header_generated_ || codec_ != stream_codec_parameters_->codec_id ||
      audio_profile_ != stream_codec_parameters_->profile ||
      sample_rate_index_ != sample_rate_index ||
      channel_configuration_ != stream_codec_parameters_->channels ||
      frame_length_ != header_plus_packet_size) {
    header_generated_ =
        GenerateAdtsHeader(stream_codec_parameters_->codec_id,
                           0,  // layer
                           stream_codec_parameters_->profile, sample_rate_index,
                           0,  // private stream
                           stream_codec_parameters_->channels,
                           0,  // originality
                           0,  // home
                           0,  // copyrighted_stream
                           0,  // copyright_ start
                           header_plus_packet_size,
                           0x7FF,  // buffer fullness
                           0,      // one frame per packet
                           hdr_);
    codec_ = stream_codec_parameters_->codec_id;
    audio_profile_ = stream_codec_parameters_->profile;
    sample_rate_index_ = sample_rate_index;
    channel_configuration_ = stream_codec_parameters_->channels;
    frame_length_ = header_plus_packet_size;
  }

  // Inform caller if the header generation failed.
  if (!header_generated_)
    return false;

  // Allocate new packet for the output.
  AVPacket dest_packet;
  if (av_new_packet(&dest_packet, header_plus_packet_size) != 0)
    return false;  // Memory allocation failure.

  memcpy(dest_packet.data, hdr_, kAdtsHeaderSize);
  memcpy(reinterpret_cast<void*>(dest_packet.data + kAdtsHeaderSize),
         reinterpret_cast<void*>(packet->data), packet->size);

  // This is a bit tricky: since the interface does not allow us to replace
  // the pointer of the old packet with a new one, we will initially copy the
  // metadata from old packet to new bigger packet.
  av_packet_copy_props(&dest_packet, packet);

  // Release the old packet.
  av_packet_unref(packet);
  *packet = dest_packet;  // Finally, replace the values in the input packet.

  return true;
}

}  // namespace media
