// 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) << "[" << __FUNCTION__ << "] "
                  << "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) << "[" << __FUNCTION__ << "] "
                  << "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
