blob: a2e688c8a7633160c92346f46827947d2fb8be40 [file] [log] [blame]
// Copyright 2013 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 CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_
#define CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_
#include <map>
#include <vector>
#include "base/basictypes.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/default_tick_clock.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_sender.h"
#include "media/cast/logging/logging_defines.h"
namespace base {
class BinaryValue;
class DictionaryValue;
class MessageLoopProxy;
} // namespace base
namespace media {
class VideoFrame;
namespace cast {
class CastEnvironment;
class FrameInput;
class RawEventSubscriberBundle;
namespace transport {
class CastTransportSender;
} // namespace transport
} // namespace cast
} // namespace media
// Breaks out functionality that is common between CastSessionDelegate and
// CastReceiverSessionDelegate.
class CastSessionDelegateBase {
public:
typedef base::Callback<void(const std::string&)> ErrorCallback;
CastSessionDelegateBase();
virtual ~CastSessionDelegateBase();
// This will start the session by configuring and creating the Cast transport
// and the Cast sender.
// Must be called before initialization of audio or video.
void StartUDP(const net::IPEndPoint& local_endpoint,
const net::IPEndPoint& remote_endpoint,
scoped_ptr<base::DictionaryValue> options,
const ErrorCallback& error_callback);
protected:
void StatusNotificationCB(
const ErrorCallback& error_callback,
media::cast::CastTransportStatus status);
virtual void ReceivePacket(scoped_ptr<media::cast::Packet> packet) = 0;
virtual void LogRawEvents(
const std::vector<media::cast::PacketEvent>& packet_events,
const std::vector<media::cast::FrameEvent>& frame_events) = 0;
base::ThreadChecker thread_checker_;
scoped_refptr<media::cast::CastEnvironment> cast_environment_;
scoped_ptr<media::cast::CastTransportSender> cast_transport_;
// Proxy to the IO message loop.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
base::WeakPtrFactory<CastSessionDelegateBase> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CastSessionDelegateBase);
};
// This class hosts CastSender and connects it to audio/video frame input
// and network socket.
// This class is created on the render thread and destroyed on the IO
// thread. All methods are accessible only on the IO thread.
class CastSessionDelegate : public CastSessionDelegateBase {
public:
typedef base::Callback<void(const scoped_refptr<
media::cast::AudioFrameInput>&)> AudioFrameInputAvailableCallback;
typedef base::Callback<void(const scoped_refptr<
media::cast::VideoFrameInput>&)> VideoFrameInputAvailableCallback;
typedef base::Callback<void(scoped_ptr<base::BinaryValue>)> EventLogsCallback;
typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> StatsCallback;
CastSessionDelegate();
~CastSessionDelegate() override;
void StartUDP(const net::IPEndPoint& local_endpoint,
const net::IPEndPoint& remote_endpoint,
scoped_ptr<base::DictionaryValue> options,
const ErrorCallback& error_callback);
// After calling StartAudio() or StartVideo() encoding of that media will
// begin as soon as data is delivered to its sink, if the second method is
// called the first media will be restarted. It is strongly recommended not to
// deliver any data between calling the two methods.
// It's OK to call only one of the two methods.
// StartUDP must be called before these methods.
void StartAudio(const media::cast::AudioSenderConfig& config,
const AudioFrameInputAvailableCallback& callback,
const ErrorCallback& error_callback);
void StartVideo(const media::cast::VideoSenderConfig& config,
const VideoFrameInputAvailableCallback& callback,
const ErrorCallback& error_callback,
const media::cast::CreateVideoEncodeAcceleratorCallback&
create_vea_cb,
const media::cast::CreateVideoEncodeMemoryCallback&
create_video_encode_mem_cb);
void ToggleLogging(bool is_audio, bool enable);
void GetEventLogsAndReset(bool is_audio,
const std::string& extra_data, const EventLogsCallback& callback);
void GetStatsAndReset(bool is_audio, const StatsCallback& callback);
protected:
// Called to report back operational status changes. The first time this is
// called with STATUS_INITIALIZED will result in running the "frame input
// available" callback, to indicate the session is ready to accept incoming
// audio/video frames. If this is called with an error that has halted the
// session, the |error_callback| provided to StartXXX() will be run. This
// method may be called multiple times during the session to indicate codec
// re-initializations are taking place and/or runtime errors have occurred.
void OnOperationalStatusChange(
bool is_for_audio,
const ErrorCallback& error_callback,
media::cast::OperationalStatus result);
private:
void ReceivePacket(scoped_ptr<media::cast::Packet> packet) override;
// Adds logs collected from transport on browser side.
void LogRawEvents(const std::vector<media::cast::PacketEvent>& packet_events,
const std::vector<media::cast::FrameEvent>& frame_events)
override;
scoped_ptr<media::cast::CastSender> cast_sender_;
AudioFrameInputAvailableCallback audio_frame_input_available_callback_;
VideoFrameInputAvailableCallback video_frame_input_available_callback_;
scoped_ptr<media::cast::RawEventSubscriberBundle> event_subscribers_;
base::WeakPtrFactory<CastSessionDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CastSessionDelegate);
};
#endif // CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_