// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_DECODED_AUDIO_INTERNAL_H_
#define STARBOARD_SHARED_STARBOARD_PLAYER_DECODED_AUDIO_INTERNAL_H_

#include "starboard/common/ref_counted.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/media.h"
#include "starboard/shared/internal_only.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {

// Decoded audio frames produced by an audio decoder.  It can contain multiple
// frames with continuous timestamps.
// It doesn't have a specific storage type and sample type.  The decoder and the
// renderer will determine the proper storage type and sample type in their own
// way.
class DecodedAudio : public RefCountedThreadSafe<DecodedAudio> {
 public:
  DecodedAudio();  // Signal an EOS.
  DecodedAudio(int channels,
               SbMediaAudioSampleType sample_type,
               SbMediaAudioFrameStorageType storage_type,
               SbTime timestamp,
               size_t size);

  int channels() const { return channels_; }
  SbMediaAudioSampleType sample_type() const { return sample_type_; }
  SbMediaAudioFrameStorageType storage_type() const { return storage_type_; }

  bool is_end_of_stream() const { return buffer_ == NULL; }
  SbTime timestamp() const { return timestamp_; }
  const uint8_t* buffer() const { return buffer_.get(); }
  size_t size() const { return size_; }

  uint8_t* buffer() { return buffer_.get(); }
  int frames() const;

  void SwitchFormatTo(SbMediaAudioSampleType new_sample_type,
                      SbMediaAudioFrameStorageType new_storage_type);
  void ShrinkTo(size_t new_size);
  // During seeking, the target time can be in the middle of the DecodedAudio
  // object.  This function will adjust the object to the seek target time by
  // removing the frames in the beginning that are before the seek target time.
  void AdjustForSeekTime(int samples_per_second, SbTime seeking_to_time);

 private:
  void SwitchSampleTypeTo(SbMediaAudioSampleType new_sample_type);
  void SwitchStorageTypeTo(SbMediaAudioFrameStorageType new_storage_type);

  int channels_;
  SbMediaAudioSampleType sample_type_;
  SbMediaAudioFrameStorageType storage_type_;
  // The timestamp of the first audio frame.
  SbTime timestamp_;
  // Use scoped_array<uint8_t> instead of std::vector<uint8_t> to avoid wasting
  // time on setting content to 0.
  scoped_array<uint8_t> buffer_;
  size_t size_;

  DecodedAudio(const DecodedAudio&) = delete;
  void operator=(const DecodedAudio&) = delete;
};

}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard

#endif  // STARBOARD_SHARED_STARBOARD_PLAYER_DECODED_AUDIO_INTERNAL_H_
