/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef API_AUDIO_CODECS_AUDIO_DECODER_H_
#define API_AUDIO_CODECS_AUDIO_DECODER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "rtc_base/buffer.h"

namespace webrtc {

class AudioDecoder {
 public:
  enum SpeechType {
    kSpeech = 1,
    kComfortNoise = 2,
  };

  // Used by PacketDuration below. Save the value -1 for errors.
  enum { kNotImplemented = -2 };

  AudioDecoder() = default;
  virtual ~AudioDecoder() = default;

  AudioDecoder(const AudioDecoder&) = delete;
  AudioDecoder& operator=(const AudioDecoder&) = delete;

  class EncodedAudioFrame {
   public:
    struct DecodeResult {
      size_t num_decoded_samples;
      SpeechType speech_type;
    };

    virtual ~EncodedAudioFrame() = default;

    // Returns the duration in samples-per-channel of this audio frame.
    // If no duration can be ascertained, returns zero.
    virtual size_t Duration() const = 0;

    // Returns true if this packet contains DTX.
    virtual bool IsDtxPacket() const;

    // Decodes this frame of audio and writes the result in `decoded`.
    // `decoded` must be large enough to store as many samples as indicated by a
    // call to Duration() . On success, returns an absl::optional containing the
    // total number of samples across all channels, as well as whether the
    // decoder produced comfort noise or speech. On failure, returns an empty
    // absl::optional. Decode may be called at most once per frame object.
    virtual absl::optional<DecodeResult> Decode(
        rtc::ArrayView<int16_t> decoded) const = 0;
  };

  struct ParseResult {
    ParseResult();
    ParseResult(uint32_t timestamp,
                int priority,
                std::unique_ptr<EncodedAudioFrame> frame);
    ParseResult(ParseResult&& b);
    ~ParseResult();

    ParseResult& operator=(ParseResult&& b);

    // The timestamp of the frame is in samples per channel.
    uint32_t timestamp;
    // The relative priority of the frame compared to other frames of the same
    // payload and the same timeframe. A higher value means a lower priority.
    // The highest priority is zero - negative values are not allowed.
    int priority;
    std::unique_ptr<EncodedAudioFrame> frame;
  };

  // Let the decoder parse this payload and prepare zero or more decodable
  // frames. Each frame must be between 10 ms and 120 ms long. The caller must
  // ensure that the AudioDecoder object outlives any frame objects returned by
  // this call. The decoder is free to swap or move the data from the `payload`
  // buffer. `timestamp` is the input timestamp, in samples, corresponding to
  // the start of the payload.
  virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
                                                uint32_t timestamp);

  // TODO(bugs.webrtc.org/10098): The Decode and DecodeRedundant methods are
  // obsolete; callers should call ParsePayload instead. For now, subclasses
  // must still implement DecodeInternal.

  // Decodes `encode_len` bytes from `encoded` and writes the result in
  // `decoded`. The maximum bytes allowed to be written into `decoded` is
  // `max_decoded_bytes`. Returns the total number of samples across all
  // channels. If the decoder produced comfort noise, `speech_type`
  // is set to kComfortNoise, otherwise it is kSpeech. The desired output
  // sample rate is provided in `sample_rate_hz`, which must be valid for the
  // codec at hand.
  int Decode(const uint8_t* encoded,
             size_t encoded_len,
             int sample_rate_hz,
             size_t max_decoded_bytes,
             int16_t* decoded,
             SpeechType* speech_type);

  // Same as Decode(), but interfaces to the decoders redundant decode function.
  // The default implementation simply calls the regular Decode() method.
  int DecodeRedundant(const uint8_t* encoded,
                      size_t encoded_len,
                      int sample_rate_hz,
                      size_t max_decoded_bytes,
                      int16_t* decoded,
                      SpeechType* speech_type);

  // Indicates if the decoder implements the DecodePlc method.
  virtual bool HasDecodePlc() const;

  // Calls the packet-loss concealment of the decoder to update the state after
  // one or several lost packets. The caller has to make sure that the
  // memory allocated in `decoded` should accommodate `num_frames` frames.
  virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);

  // Asks the decoder to generate packet-loss concealment and append it to the
  // end of `concealment_audio`. The concealment audio should be in
  // channel-interleaved format, with as many channels as the last decoded
  // packet produced. The implementation must produce at least
  // requested_samples_per_channel, or nothing at all. This is a signal to the
  // caller to conceal the loss with other means. If the implementation provides
  // concealment samples, it is also responsible for "stitching" it together
  // with the decoded audio on either side of the concealment.
  // Note: The default implementation of GeneratePlc will be deleted soon. All
  // implementations must provide their own, which can be a simple as a no-op.
  // TODO(bugs.webrtc.org/9676): Remove default implementation.
  virtual void GeneratePlc(size_t requested_samples_per_channel,
                           rtc::BufferT<int16_t>* concealment_audio);

  // Resets the decoder state (empty buffers etc.).
  virtual void Reset() = 0;

  // Returns the last error code from the decoder.
  virtual int ErrorCode();

  // Returns the duration in samples-per-channel of the payload in `encoded`
  // which is `encoded_len` bytes long. Returns kNotImplemented if no duration
  // estimate is available, or -1 in case of an error.
  virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;

  // Returns the duration in samples-per-channel of the redandant payload in
  // `encoded` which is `encoded_len` bytes long. Returns kNotImplemented if no
  // duration estimate is available, or -1 in case of an error.
  virtual int PacketDurationRedundant(const uint8_t* encoded,
                                      size_t encoded_len) const;

  // Detects whether a packet has forward error correction. The packet is
  // comprised of the samples in `encoded` which is `encoded_len` bytes long.
  // Returns true if the packet has FEC and false otherwise.
  virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;

  // Returns the actual sample rate of the decoder's output. This value may not
  // change during the lifetime of the decoder.
  virtual int SampleRateHz() const = 0;

  // The number of channels in the decoder's output. This value may not change
  // during the lifetime of the decoder.
  virtual size_t Channels() const = 0;

  // The maximum number of audio channels supported by WebRTC decoders.
  static constexpr int kMaxNumberOfChannels = 24;

 protected:
  static SpeechType ConvertSpeechType(int16_t type);

  virtual int DecodeInternal(const uint8_t* encoded,
                             size_t encoded_len,
                             int sample_rate_hz,
                             int16_t* decoded,
                             SpeechType* speech_type) = 0;

  virtual int DecodeRedundantInternal(const uint8_t* encoded,
                                      size_t encoded_len,
                                      int sample_rate_hz,
                                      int16_t* decoded,
                                      SpeechType* speech_type);
};

}  // namespace webrtc
#endif  // API_AUDIO_CODECS_AUDIO_DECODER_H_
