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

// Delegate calls from WebCore::MediaPlayerPrivate to Chrome's video player.
// It contains PipelineImpl which is the actual media player pipeline, it glues
// the media player pipeline, data source, audio renderer and renderer.
// PipelineImpl would creates multiple threads and access some public methods
// of this class, so we need to be extra careful about concurrent access of
// methods and members.
//
// WebMediaPlayerImpl works with multiple objects, the most important ones are:
//
// media::PipelineImpl
//   The media playback pipeline.
//
// WebVideoRenderer
//   Video renderer object.
//
// WebMediaPlayerImpl::Proxy
//   Proxies methods calls from the media pipeline to WebKit.
//
// WebKit::WebMediaPlayerClient
//   WebKit client of this media player object.
//
// The following diagram shows the relationship of these objects:
//   (note: ref-counted reference is marked by a "r".)
//
// WebMediaPlayerImpl ------> PipelineImpl
//    |            ^               | r
//    |            |               v
//    |            |        WebVideoRenderer
//    |            |          ^ r
//    |            |          |
//    |      r     |    r     |
//    .------>   Proxy  <-----.
//    |
//    |
//    v
// WebMediaPlayerClient
//
// Notice that Proxy and WebVideoRenderer are referencing each other. This
// interdependency has to be treated carefully.
//
// Other issues:
// During tear down of the whole browser or a tab, the DOM tree may not be
// destructed nicely, and there will be some dangling media threads trying to
// the main thread, so we need this class to listen to destruction event of the
// main thread and cleanup the media threads when the even is received. Also
// at destruction of this class we will need to unhook it from destruction event
// list of the main thread.

#ifndef WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_
#define WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/threading/thread.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "media/base/filters.h"
#include "media/base/message_loop_factory.h"
#include "media/base/pipeline.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "webkit/glue/media/web_data_source.h"

class GURL;

namespace WebKit {
class WebFrame;
}

namespace webkit_glue {

class MediaResourceLoaderBridgeFactory;
class WebVideoRenderer;

class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
                           public MessageLoop::DestructionObserver {
 public:
  // A proxy class that dispatches method calls from the media pipeline to
  // WebKit. Since there are multiple threads in the media pipeline and there's
  // need for the media pipeline to call to WebKit, e.g. repaint requests,
  // initialization events, etc, we have this class to bridge all method calls
  // from the media pipeline on different threads and serialize these calls
  // on the render thread.
  // Because of the nature of this object that it works with different threads,
  // it is made ref-counted.
  class Proxy : public base::RefCountedThreadSafe<Proxy> {
   public:
    Proxy(MessageLoop* render_loop,
          WebMediaPlayerImpl* webmediaplayer);

    // Methods for Filter -> WebMediaPlayerImpl communication.
    void Repaint();
    void SetVideoRenderer(scoped_refptr<WebVideoRenderer> video_renderer);
    WebDataSourceBuildObserverHack* GetBuildObserver();

    // Methods for WebMediaPlayerImpl -> Filter communication.
    void Paint(SkCanvas* canvas, const gfx::Rect& dest_rect);
    void SetSize(const gfx::Rect& rect);
    void Detach();
    void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out);
    void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame);
    bool HasSingleOrigin();
    void AbortDataSources();

    // Methods for PipelineImpl -> WebMediaPlayerImpl communication.
    void PipelineInitializationCallback(media::PipelineStatus status);
    void PipelineSeekCallback(media::PipelineStatus status);
    void PipelineEndedCallback(media::PipelineStatus status);
    void PipelineErrorCallback(media::PipelineStatus error);
    void NetworkEventCallback(media::PipelineStatus status);

    // Returns the message loop used by the proxy.
    MessageLoop* message_loop() { return render_loop_; }

   private:
    friend class base::RefCountedThreadSafe<Proxy>;

    virtual ~Proxy();

    // Adds a data source to data_sources_.
    void AddDataSource(WebDataSource* data_source);

    // Invoke |webmediaplayer_| to perform a repaint.
    void RepaintTask();

    // Notify |webmediaplayer_| that initialization has finished.
    void PipelineInitializationTask(media::PipelineStatus status);

    // Notify |webmediaplayer_| that a seek has finished.
    void PipelineSeekTask(media::PipelineStatus status);

    // Notify |webmediaplayer_| that the media has ended.
    void PipelineEndedTask(media::PipelineStatus status);

    // Notify |webmediaplayer_| that a pipeline error has occurred during
    // playback.
    void PipelineErrorTask(media::PipelineStatus error);

    // Notify |webmediaplayer_| that there's a network event.
    void NetworkEventTask(media::PipelineStatus status);

    // The render message loop where WebKit lives.
    MessageLoop* render_loop_;
    WebMediaPlayerImpl* webmediaplayer_;

    base::Lock data_sources_lock_;
    typedef std::list<scoped_refptr<WebDataSource> > DataSourceList;
    DataSourceList data_sources_;
    scoped_ptr<WebDataSourceBuildObserverHack> build_observer_;

    scoped_refptr<WebVideoRenderer> video_renderer_;

    base::Lock lock_;
    int outstanding_repaints_;
  };

  // Construct a WebMediaPlayerImpl with reference to the client, and media
  // filter collection. By providing the filter collection the implementor can
  // provide more specific media filters that does resource loading and
  // rendering. |collection| should contain filter factories for:
  // 1. Data source
  // 2. Audio renderer
  // 3. Video renderer (optional)
  //
  // There are some default filters provided by this method:
  // 1. FFmpeg demuxer
  // 2. FFmpeg audio decoder
  // 3. FFmpeg video decoder
  // 4. Video renderer
  // 5. Null audio renderer
  // The video renderer provided by this class is using the graphics context
  // provided by WebKit to perform renderering. The simple data source does
  // resource loading by loading the whole resource object into memory. Null
  // audio renderer is a fake audio device that plays silence. Provider of the
  // |collection| can override the default filters by adding extra filters to
  // |collection| before calling this method.
  //
  // Callers must call |Initialize()| before they can use the object.
  WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
                     media::FilterCollection* collection,
                     media::MessageLoopFactory* message_loop_factory);
  virtual ~WebMediaPlayerImpl();

  // Finalizes initialization of the object.
  bool Initialize(
      WebKit::WebFrame* frame,
      bool use_simple_data_source,
      scoped_refptr<WebVideoRenderer> web_video_renderer);

  virtual void load(const WebKit::WebURL& url);
  virtual void cancelLoad();

  // Playback controls.
  virtual void play();
  virtual void pause();
  virtual bool supportsFullscreen() const;
  virtual bool supportsSave() const;
  virtual void seek(float seconds);
  virtual void setEndTime(float seconds);
  virtual void setRate(float rate);
  virtual void setVolume(float volume);
  virtual void setVisible(bool visible);
  virtual void setPreload(WebKit::WebMediaPlayer::Preload preload);
  virtual bool totalBytesKnown();
  virtual const WebKit::WebTimeRanges& buffered();
  virtual float maxTimeSeekable() const;

  // Methods for painting.
  virtual void setSize(const WebKit::WebSize& size);

  virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);

  // True if the loaded media has a playable video/audio track.
  virtual bool hasVideo() const;
  virtual bool hasAudio() const;

  // Dimensions of the video.
  virtual WebKit::WebSize naturalSize() const;

  // Getters of playback state.
  virtual bool paused() const;
  virtual bool seeking() const;
  virtual float duration() const;
  virtual float currentTime() const;

  // Get rate of loading the resource.
  virtual int32 dataRate() const;

  // Internal states of loading and network.
  // TODO(hclam): Ask the pipeline about the state rather than having reading
  // them from members which would cause race conditions.
  virtual WebKit::WebMediaPlayer::NetworkState networkState() const;
  virtual WebKit::WebMediaPlayer::ReadyState readyState() const;

  virtual unsigned long long bytesLoaded() const;
  virtual unsigned long long totalBytes() const;

  virtual bool hasSingleSecurityOrigin() const;
  virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const;

  virtual unsigned decodedFrameCount() const;
  virtual unsigned droppedFrameCount() const;
  virtual unsigned audioDecodedByteCount() const;
  virtual unsigned videoDecodedByteCount() const;

  virtual WebKit::WebVideoFrame* getCurrentFrame();
  virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame);

  // As we are closing the tab or even the browser, |main_loop_| is destroyed
  // even before this object gets destructed, so we need to know when
  // |main_loop_| is being destroyed and we can stop posting repaint task
  // to it.
  virtual void WillDestroyCurrentMessageLoop();

  void Repaint();

  void OnPipelineInitialize(media::PipelineStatus status);

  void OnPipelineSeek(media::PipelineStatus status);

  void OnPipelineEnded(media::PipelineStatus status);

  void OnPipelineError(media::PipelineStatus error);

  void OnNetworkEvent(media::PipelineStatus status);

 private:
  // Helpers that set the network/ready state and notifies the client if
  // they've changed.
  void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state);
  void SetReadyState(WebKit::WebMediaPlayer::ReadyState state);

  // Destroy resources held.
  void Destroy();

  // Getter method to |client_|.
  WebKit::WebMediaPlayerClient* GetClient();

  // TODO(hclam): get rid of these members and read from the pipeline directly.
  WebKit::WebMediaPlayer::NetworkState network_state_;
  WebKit::WebMediaPlayer::ReadyState ready_state_;

  // Keep a list of buffered time ranges.
  WebKit::WebTimeRanges buffered_;

  // Message loops for posting tasks between Chrome's main thread. Also used
  // for DCHECKs so methods calls won't execute in the wrong thread.
  MessageLoop* main_loop_;

  // A collection of filters.
  scoped_ptr<media::FilterCollection> filter_collection_;

  // The actual pipeline and the thread it runs on.
  scoped_refptr<media::Pipeline> pipeline_;

  scoped_ptr<media::MessageLoopFactory> message_loop_factory_;

  // Playback state.
  //
  // TODO(scherkus): we have these because Pipeline favours the simplicity of a
  // single "playback rate" over worrying about paused/stopped etc...  It forces
  // all clients to manage the pause+playback rate externally, but is that
  // really a bad thing?
  //
  // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want
  // to hang the render thread during pause(), we record the time at the same
  // time we pause and then return that value in currentTime().  Otherwise our
  // clock can creep forward a little bit while the asynchronous
  // SetPlaybackRate(0) is being executed.
  bool paused_;
  bool seeking_;
  float playback_rate_;
  base::TimeDelta paused_time_;

  WebKit::WebMediaPlayerClient* client_;

  scoped_refptr<Proxy> proxy_;

#if WEBKIT_USING_CG
  scoped_ptr<skia::PlatformCanvas> skia_canvas_;
#endif

  DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
};

}  // namespace webkit_glue

#endif  // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_
