1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
6#define CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
7
8#include <vector>
9
10#include "base/containers/hash_tables.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/weak_ptr.h"
13#include "base/threading/non_thread_safe.h"
14#include "content/common/gpu/client/command_buffer_proxy_impl.h"
15#include "ipc/ipc_listener.h"
16#include "media/video/video_encode_accelerator.h"
17
18namespace gfx {
19
20class Size;
21
22}  // namespace gfx
23
24namespace media {
25
26class VideoFrame;
27
28}  // namespace media
29
30namespace content {
31
32class GpuChannelHost;
33
34// This class is the renderer-side host for the VideoEncodeAccelerator in the
35// GPU process, coordinated over IPC.
36class GpuVideoEncodeAcceleratorHost
37    : public IPC::Listener,
38      public media::VideoEncodeAccelerator,
39      public CommandBufferProxyImpl::DeletionObserver,
40      public base::NonThreadSafe {
41 public:
42  // |this| is guaranteed not to outlive |channel| and |impl|.  (See comments
43  // for |channel_| and |impl_|.)
44  GpuVideoEncodeAcceleratorHost(GpuChannelHost* channel,
45                                CommandBufferProxyImpl* impl);
46
47  // IPC::Listener implementation.
48  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
49  virtual void OnChannelError() OVERRIDE;
50
51  // media::VideoEncodeAccelerator implementation.
52  virtual std::vector<SupportedProfile> GetSupportedProfiles() OVERRIDE;
53  virtual bool Initialize(media::VideoFrame::Format input_format,
54                          const gfx::Size& input_visible_size,
55                          media::VideoCodecProfile output_profile,
56                          uint32 initial_bitrate,
57                          Client* client) OVERRIDE;
58  virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
59                      bool force_keyframe) OVERRIDE;
60  virtual void UseOutputBitstreamBuffer(
61      const media::BitstreamBuffer& buffer) OVERRIDE;
62  virtual void RequestEncodingParametersChange(uint32 bitrate,
63                                               uint32 framerate_num) OVERRIDE;
64  virtual void Destroy() OVERRIDE;
65
66  // CommandBufferProxyImpl::DeletionObserver implemetnation.
67  virtual void OnWillDeleteImpl() OVERRIDE;
68
69 private:
70  // Only Destroy() should be deleting |this|.
71  virtual ~GpuVideoEncodeAcceleratorHost();
72
73  // Notify |client_| of an error.  Posts a task to avoid re-entrancy.
74  void PostNotifyError(Error);
75
76  void Send(IPC::Message* message);
77
78  // IPC handlers, proxying media::VideoEncodeAccelerator::Client for the GPU
79  // process.  Should not be called directly.
80  void OnRequireBitstreamBuffers(uint32 input_count,
81                                 const gfx::Size& input_coded_size,
82                                 uint32 output_buffer_size);
83  void OnNotifyInputDone(int32 frame_id);
84  void OnBitstreamBufferReady(int32 bitstream_buffer_id,
85                              uint32 payload_size,
86                              bool key_frame);
87  void OnNotifyError(Error error);
88
89  // Unowned reference to the GpuChannelHost to send IPC messages to the GPU
90  // process.  |channel_| outlives |impl_|, so the reference is always valid as
91  // long as it is not NULL.
92  GpuChannelHost* channel_;
93
94  // Route ID for the associated encoder in the GPU process.
95  int32 encoder_route_id_;
96
97  // The client that will receive callbacks from the encoder.
98  Client* client_;
99
100  // Unowned reference to the CommandBufferProxyImpl that created us.  |this|
101  // registers as a DeletionObserver of |impl_|, so the reference is always
102  // valid as long as it is not NULL.
103  CommandBufferProxyImpl* impl_;
104
105  // media::VideoFrames sent to the encoder.
106  // base::IDMap not used here, since that takes pointers, not scoped_refptr.
107  typedef base::hash_map<int32, scoped_refptr<media::VideoFrame> > FrameMap;
108  FrameMap frame_map_;
109
110  // ID serial number for the next frame to send to the GPU process.
111  int32 next_frame_id_;
112
113  // WeakPtr factory for posting tasks back to itself.
114  base::WeakPtrFactory<GpuVideoEncodeAcceleratorHost> weak_this_factory_;
115
116  DISALLOW_COPY_AND_ASSIGN(GpuVideoEncodeAcceleratorHost);
117};
118
119}  // namespace content
120
121#endif  // CONTENT_COMMON_GPU_CLIENT_GPU_VIDEO_ENCODE_ACCELERATOR_HOST_H_
122