// Copyright 2012 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 COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_
#define COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_

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

#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "cobalt/media/base/decoder_buffer.h"
#include "cobalt/media/base/demuxer.h"
#include "cobalt/media/base/demuxer_stream.h"
#include "cobalt/media/base/media_log.h"
#include "cobalt/media/base/ranges.h"
#include "cobalt/media/progressive/progressive_parser.h"

namespace cobalt {
namespace media {

class DecoderBuffer;
class ProgressiveDemuxer;

class ProgressiveDemuxerStream : public DemuxerStream {
 public:
  ProgressiveDemuxerStream(ProgressiveDemuxer* demuxer, Type type);

  // DemuxerStream implementation
  void Read(const ReadCB& read_cb) override;
  AudioDecoderConfig audio_decoder_config() override;
  VideoDecoderConfig video_decoder_config() override;
  Type type() const override;
  void EnableBitstreamConverter() override;
  bool SupportsConfigChanges() override { return false; }
  VideoRotation video_rotation() override { return VIDEO_ROTATION_0; }
  bool enabled() const override { return true; }
  void set_enabled(bool enabled, base::TimeDelta timestamp) override {
    DCHECK(enabled);
  }
  void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override {
    NOTREACHED();
  }

  // Functions used by ProgressiveDemuxer
  Ranges<base::TimeDelta> GetBufferedRanges();
  void EnqueueBuffer(scoped_refptr<DecoderBuffer> buffer);
  void FlushBuffers();
  void Stop();
  base::TimeDelta GetLastBufferTimestamp() const;
  size_t GetTotalBufferSize() const;
  size_t GetTotalBufferCount() const;

 private:
  // The Ranges object doesn't offer a complement object so we rebuild
  // enqueued ranges from the union of all of the buffers in the queue.
  // Call me whenever _removing_ data from buffer_queue_.
  void RebuildEnqueuedRanges_Locked();

  // non-owning pointer to avoid circular reference
  ProgressiveDemuxer* demuxer_;
  Type type_;

  // Used to protect everything below.
  mutable base::Lock lock_;
  // Keeps track of all time ranges this object has seen since creation.
  // The demuxer uses these ranges to update the pipeline about what data
  // it has demuxed.
  Ranges<base::TimeDelta> buffered_ranges_;
  // The last timestamp of buffer enqueued. This is used in two places:
  //   1. Used with the timestamp of the current frame to calculate the
  //      buffer range.
  //   2. Used by the demuxer to deteminate what type of frame to get next.
  base::TimeDelta last_buffer_timestamp_ = kNoTimestamp;
  bool stopped_ = false;

  typedef std::deque<scoped_refptr<DecoderBuffer> > BufferQueue;
  BufferQueue buffer_queue_;

  typedef std::deque<ReadCB> ReadQueue;
  ReadQueue read_queue_;

  size_t total_buffer_size_ = 0;
  size_t total_buffer_count_ = 0;

  DISALLOW_COPY_AND_ASSIGN(ProgressiveDemuxerStream);
};

class MEDIA_EXPORT ProgressiveDemuxer : public Demuxer {
 public:
  ProgressiveDemuxer(
      const scoped_refptr<base::SingleThreadTaskRunner>& message_loop,
      DecoderBuffer::Allocator* buffer_allocator, DataSource* data_source,
      const scoped_refptr<MediaLog>& media_log);
  ~ProgressiveDemuxer() override;

  // Demuxer implementation.
  std::string GetDisplayName() const override { return "ProgressiveDemuxer"; }
  void Initialize(DemuxerHost* host, const PipelineStatusCB& status_cb,
                  bool enable_text_tracks) override;
  void AbortPendingReads() override {}
  void StartWaitingForSeek(base::TimeDelta seek_time) override {}
  void CancelPendingSeek(base::TimeDelta seek_time) override {}
  void Stop() override;
  void Seek(base::TimeDelta time, const PipelineStatusCB& cb) override;
  DemuxerStream* GetStream(DemuxerStream::Type type) override;
  base::TimeDelta GetStartTime() const override;
  base::Time GetTimelineOffset() const override { return base::Time(); }
  int64_t GetMemoryUsage() const override {
    NOTREACHED();
    return 0;
  }
  void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids,
                                   base::TimeDelta currTime) override {
    NOTREACHED();
  }
  void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids,
                                   base::TimeDelta currTime) override {
    NOTREACHED();
  }

  // TODO: Consider move the following functions to private section.

  // Issues a task to the demuxer to identify the next buffer of provided type
  // in the stream, allocate memory to contain that buffer, download the bytes
  // in to it, and enqueue the data in the appropriate demuxer stream.
  void Request(DemuxerStream::Type type);

  // The DemuxerStream objects ask their parent ProgressiveDemuxer stream class
  // for these configuration data rather than duplicating in the child classes
  const AudioDecoderConfig& AudioConfig();
  const VideoDecoderConfig& VideoConfig();

  // Provide access to ProgressiveDemuxerStream.
  bool MessageLoopBelongsToCurrentThread() const;

 private:
  void ParseConfigDone(const PipelineStatusCB& status_cb,
                       PipelineStatus status);
  void DataSourceStopped(const base::Closure& callback);
  bool HasStopCalled();

  // methods that perform blocking I/O, and are therefore run on the
  // blocking_thread_ download enough of the stream to parse the configuration.
  void ParseConfigBlocking(const PipelineStatusCB& status_cb);
  void AllocateBuffer();
  void Download(scoped_refptr<DecoderBuffer> buffer);
  void IssueNextRequest();
  void SeekTask(base::TimeDelta time, const PipelineStatusCB& cb);

  scoped_refptr<base::SingleThreadTaskRunner> message_loop_;
  DecoderBuffer::Allocator* buffer_allocator_;
  DemuxerHost* host_;

  // Thread on which all blocking operations are executed.
  base::Thread blocking_thread_;
  DataSource* data_source_;
  scoped_refptr<MediaLog> media_log_;
  scoped_refptr<DataSourceReader> reader_;

  base::Lock lock_for_stopped_;
  bool stopped_;
  bool flushing_;

  std::unique_ptr<ProgressiveDemuxerStream> audio_demuxer_stream_;
  std::unique_ptr<ProgressiveDemuxerStream> video_demuxer_stream_;
  scoped_refptr<ProgressiveParser> parser_;

  scoped_refptr<AvcAccessUnit> requested_au_;
  bool audio_reached_eos_;
  bool video_reached_eos_;
};

}  // namespace media
}  // namespace cobalt

#endif  // COBALT_MEDIA_PROGRESSIVE_PROGRESSIVE_DEMUXER_H_
