// Copyright 2022 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_FFMPEG_FFMPEG_DEMUXER_IMPL_H_
#define STARBOARD_SHARED_FFMPEG_FFMPEG_DEMUXER_IMPL_H_

#include <deque>
#include <memory>
#include <vector>

#include "cobalt/extension/demuxer.h"
#include "starboard/shared/ffmpeg/ffmpeg_common.h"
#include "starboard/shared/ffmpeg/ffmpeg_demuxer.h"
#include "starboard/shared/ffmpeg/ffmpeg_demuxer_impl_interface.h"
#include "starboard/time.h"

namespace starboard {
namespace shared {
namespace ffmpeg {

class FFMPEGDispatch;

// Forward class declaration of the explicit specialization with value FFMPEG.
template <>
class FFmpegDemuxerImpl<FFMPEG>;

// Declare the explicit specialization of the class with value FFMPEG.
template <>
class FFmpegDemuxerImpl<FFMPEG> : public FFmpegDemuxer {
 public:
  // Creates an FFmpegDemuxer instance for a specific version of FFmpeg. Returns
  // null if the version of FFmpeg that is present is not supported.
  static std::unique_ptr<FFmpegDemuxer> Create(
      CobaltExtensionDemuxerDataSource* data_source);

  ~FFmpegDemuxerImpl() override;

  // FFmpegDemuxer implementation:
  CobaltExtensionDemuxerStatus Initialize() override;
  bool HasAudioStream() const override;
  bool HasVideoStream() const override;
  const CobaltExtensionDemuxerAudioDecoderConfig& GetAudioConfig()
      const override;
  const CobaltExtensionDemuxerVideoDecoderConfig& GetVideoConfig()
      const override;
  SbTime GetDuration() const override;
  SbTime GetStartTime() const override;
  SbTime GetTimelineOffset() const override;
  void Read(CobaltExtensionDemuxerStreamType type,
            CobaltExtensionDemuxerReadCB read_cb,
            void* read_cb_user_data) override;
  CobaltExtensionDemuxerStatus Seek(int64_t seek_time_us) override;

 private:
#if LIBAVUTIL_VERSION_INT >= LIBAVUTIL_VERSION_52_8
  struct ScopedPtrAVFreeContext {
    void operator()(void* ptr) const;
  };
#endif  // LIBAVUTIL_VERSION_INT >= LIBAVUTIL_VERSION_52_8

  struct ScopedPtrAVFree {
    void operator()(void* ptr) const;
  };

  struct ScopedPtrAVFreePacket {
    void operator()(void* ptr) const;
  };

  using ScopedAVPacket = std::unique_ptr<AVPacket, ScopedPtrAVFreePacket>;

  explicit FFmpegDemuxerImpl(CobaltExtensionDemuxerDataSource* data_source);

  // Creates an empty ScopedAVPacket. The returned ScopedAVPacket will not be
  // null.
  // Since different versions of FFmpeg require different functions to create an
  // AVPacket, this function abstracts away those differences.
  ScopedAVPacket CreateScopedAVPacket();

  // Returns the next packet of type |type|, or nullptr if EoS has been reached
  // or an error was encountered.
  ScopedAVPacket GetNextPacket(CobaltExtensionDemuxerStreamType type);

  // Returns a buffered packet of type |type|, or nullptr if no buffered packet
  // is available.
  ScopedAVPacket GetBufferedPacket(CobaltExtensionDemuxerStreamType type);

  // Pushes |packet| into the queue specified by |type|.
  void BufferPacket(ScopedAVPacket packet,
                    CobaltExtensionDemuxerStreamType type);

  bool ParseAudioConfig(AVStream* audio_stream,
                        CobaltExtensionDemuxerAudioDecoderConfig* config);

  bool ParseVideoConfig(AVStream* video_stream,
                        CobaltExtensionDemuxerVideoDecoderConfig* config);

  CobaltExtensionDemuxerDataSource* data_source_ = nullptr;
  AVStream* video_stream_ = nullptr;
  AVStream* audio_stream_ = nullptr;
  std::deque<ScopedAVPacket> video_packets_;
  std::deque<ScopedAVPacket> audio_packets_;

  std::vector<uint8_t> extra_audio_data_;
  std::vector<uint8_t> extra_video_data_;

  // These will only be properly populated if the corresponding AVStream is not
  // null.
  CobaltExtensionDemuxerAudioDecoderConfig audio_config_ = {};
  CobaltExtensionDemuxerVideoDecoderConfig video_config_ = {};

  bool initialized_ = false;
  int64_t start_time_ = 0L;
  int64_t duration_us_ = 0L;
  int64_t timeline_offset_us_ = 0L;

  // FFmpeg-related structs.
  std::unique_ptr<AVIOContext, ScopedPtrAVFree> avio_context_;
  AVFormatContext* format_context_ = nullptr;
};

}  // namespace ffmpeg
}  // namespace shared
}  // namespace starboard

#endif  // STARBOARD_SHARED_FFMPEG_FFMPEG_DEMUXER_IMPL_H_
