// Copyright (c) 2012 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.

#ifndef COBALT_MEDIA_BASE_DEMUXER_STREAM_H_
#define COBALT_MEDIA_BASE_DEMUXER_STREAM_H_

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cobalt/media/base/media_export.h"
#include "cobalt/media/base/video_rotation.h"

namespace cobalt {
namespace media {

class AudioDecoderConfig;
class DecoderBuffer;
class VideoDecoderConfig;

class MEDIA_EXPORT DemuxerStream {
 public:
  enum Type {
    UNKNOWN,
    AUDIO,
    VIDEO,
    TEXT,
    NUM_TYPES,  // Always keep this entry as the last one!
  };

  enum Liveness {
    LIVENESS_UNKNOWN,
    LIVENESS_RECORDED,
    LIVENESS_LIVE,
  };

  // Status returned in the Read() callback.
  //  kOk : Indicates the second parameter is Non-NULL and contains media data
  //        or the end of the stream.
  //  kAborted : Indicates an aborted Read(). This can happen if the
  //             DemuxerStream gets flushed and doesn't have any more data to
  //             return. The second parameter MUST be NULL when this status is
  //             returned.
  //  kConfigChange : Indicates that the AudioDecoderConfig or
  //                  VideoDecoderConfig for the stream has changed.
  //                  The DemuxerStream expects an audio_decoder_config() or
  //                  video_decoder_config() call before Read() will start
  //                  returning DecoderBuffers again. The decoder will need this
  //                  new configuration to properly decode the buffers read
  //                  from this point forward. The second parameter MUST be NULL
  //                  when this status is returned.
  //                  This will only be returned if SupportsConfigChanges()
  //                  returns 'true' for this DemuxerStream.
  enum Status {
    kOk,
    kAborted,
    kConfigChanged,
  };

  // Request a buffer to returned via the provided callback.
  //
  // The first parameter indicates the status of the read.
  // The second parameter is non-NULL and contains media data
  // or the end of the stream if the first parameter is kOk. NULL otherwise.
  typedef base::Callback<void(Status, const scoped_refptr<DecoderBuffer>&)>
      ReadCB;
  virtual void Read(const ReadCB& read_cb) = 0;

  // Returns the audio/video decoder configuration. It is an error to call the
  // audio method on a video stream and vice versa. After |kConfigChanged| is
  // returned in a Read(), the caller should call this method again to retrieve
  // the new config.
  virtual AudioDecoderConfig audio_decoder_config() = 0;
  virtual VideoDecoderConfig video_decoder_config() = 0;

  // Returns the type of stream.
  virtual Type type() const = 0;

  // Returns liveness of the streams provided, i.e. whether recorded or live.
  virtual Liveness liveness() const;

  virtual void EnableBitstreamConverter();

  // Whether or not this DemuxerStream allows midstream configuration changes.
  //
  // A DemuxerStream that returns 'true' to this may return the 'kConfigChange'
  // status from a Read() call. In this case the client is expected to be
  // capable of taking appropriate action to handle config changes. Otherwise
  // audio_decoder_config() and video_decoder_config()'s return values are
  // guaranteed to remain constant, and the client may make optimizations based
  // on this.
  virtual bool SupportsConfigChanges() = 0;

  virtual VideoRotation video_rotation() = 0;

  // Indicates whether a DemuxerStream is currently enabled (i.e. should be
  // decoded and rendered) or not.
  virtual bool enabled() const = 0;

  // Disables and re-enables the stream. Reading from a disabled stream will
  // return an end-of-stream (EOS) buffer. When a stream is re-enabled, it needs
  // to know the current playback position |timestamp| in order to resume
  // reading data from a key frame preceeding the |timestamp|.
  virtual void set_enabled(bool enabled, base::TimeDelta timestamp) = 0;

  // The StreamStatusChangeCB allows DemuxerStream clients to receive
  // notifications about the stream being disabled or enabled.
  // The first parameter indicates whether the stream is enabled or disabled.
  // The second parameter is the playback position when the change occured.
  typedef base::Callback<void(bool, base::TimeDelta)> StreamStatusChangeCB;
  virtual void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) = 0;

 protected:
  // Only allow concrete implementations to get deleted.
  virtual ~DemuxerStream();
};

}  // namespace media
}  // namespace cobalt

#endif  // COBALT_MEDIA_BASE_DEMUXER_STREAM_H_
