1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  *
10  */
11 
12 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_VP9_IMPL_H_
13 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_VP9_IMPL_H_
14 
15 #include <vector>
16 
17 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
18 #include "webrtc/modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
19 
20 #include "vpx/svc_context.h"
21 #include "vpx/vpx_decoder.h"
22 #include "vpx/vpx_encoder.h"
23 
24 namespace webrtc {
25 
26 class ScreenshareLayersVP9;
27 
28 class VP9EncoderImpl : public VP9Encoder {
29  public:
30   VP9EncoderImpl();
31 
32   virtual ~VP9EncoderImpl();
33 
34   int Release() override;
35 
36   int InitEncode(const VideoCodec* codec_settings,
37                  int number_of_cores,
38                  size_t max_payload_size) override;
39 
40   int Encode(const VideoFrame& input_image,
41              const CodecSpecificInfo* codec_specific_info,
42              const std::vector<FrameType>* frame_types) override;
43 
44   int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
45 
46   int SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
47 
48   int SetRates(uint32_t new_bitrate_kbit, uint32_t frame_rate) override;
49 
OnDroppedFrame()50   void OnDroppedFrame() override {}
51 
52   const char* ImplementationName() const override;
53 
54   struct LayerFrameRefSettings {
55     int8_t upd_buf = -1;   // -1 - no update,    0..7 - update buffer 0..7
56     int8_t ref_buf1 = -1;  // -1 - no reference, 0..7 - reference buffer 0..7
57     int8_t ref_buf2 = -1;  // -1 - no reference, 0..7 - reference buffer 0..7
58     int8_t ref_buf3 = -1;  // -1 - no reference, 0..7 - reference buffer 0..7
59   };
60 
61   struct SuperFrameRefSettings {
62     LayerFrameRefSettings layer[kMaxVp9NumberOfSpatialLayers];
63     uint8_t start_layer = 0;  // The first spatial layer to be encoded.
64     uint8_t stop_layer = 0;   // The last spatial layer to be encoded.
65     bool is_keyframe = false;
66   };
67 
68  private:
69   // Determine number of encoder threads to use.
70   int NumberOfThreads(int width, int height, int number_of_cores);
71 
72   // Call encoder initialize function and set control settings.
73   int InitAndSetControlSettings(const VideoCodec* inst);
74 
75   void PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
76                              const vpx_codec_cx_pkt& pkt,
77                              uint32_t timestamp);
78 
79   bool ExplicitlyConfiguredSpatialLayers() const;
80   bool SetSvcRates();
81 
82   // Used for flexible mode to set the flags and buffer references used
83   // by the encoder. Also calculates the references used by the RTP
84   // packetizer.
85   //
86   // Has to be called for every frame (keyframes included) to update the
87   // state used to calculate references.
88   vpx_svc_ref_frame_config GenerateRefsAndFlags(
89       const SuperFrameRefSettings& settings);
90 
91   virtual int GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt);
92 
93   // Callback function for outputting packets per spatial layer.
94   static void EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt,
95                                                void* user_data);
96 
97   // Determine maximum target for Intra frames
98   //
99   // Input:
100   //    - optimal_buffer_size : Optimal buffer size
101   // Return Value             : Max target size for Intra frames represented as
102   //                            percentage of the per frame bandwidth
103   uint32_t MaxIntraTarget(uint32_t optimal_buffer_size);
104 
105   EncodedImage encoded_image_;
106   EncodedImageCallback* encoded_complete_callback_;
107   VideoCodec codec_;
108   bool inited_;
109   int64_t timestamp_;
110   uint16_t picture_id_;
111   int cpu_speed_;
112   uint32_t rc_max_intra_target_;
113   vpx_codec_ctx_t* encoder_;
114   vpx_codec_enc_cfg_t* config_;
115   vpx_image_t* raw_;
116   SvcInternal_t svc_internal_;
117   const VideoFrame* input_image_;
118   GofInfoVP9 gof_;       // Contains each frame's temporal information for
119                          // non-flexible mode.
120   uint8_t tl0_pic_idx_;  // Only used in non-flexible mode.
121   size_t frames_since_kf_;
122   uint8_t num_temporal_layers_;
123   uint8_t num_spatial_layers_;
124 
125   // Used for flexible mode.
126   bool is_flexible_mode_;
127   int64_t buffer_updated_at_frame_[kNumVp9Buffers];
128   int64_t frames_encoded_;
129   uint8_t num_ref_pics_[kMaxVp9NumberOfSpatialLayers];
130   uint8_t p_diff_[kMaxVp9NumberOfSpatialLayers][kMaxVp9RefPics];
131   rtc::scoped_ptr<ScreenshareLayersVP9> spatial_layer_;
132 };
133 
134 class VP9DecoderImpl : public VP9Decoder {
135  public:
136   VP9DecoderImpl();
137 
138   virtual ~VP9DecoderImpl();
139 
140   int InitDecode(const VideoCodec* inst, int number_of_cores) override;
141 
142   int Decode(const EncodedImage& input_image,
143              bool missing_frames,
144              const RTPFragmentationHeader* fragmentation,
145              const CodecSpecificInfo* codec_specific_info,
146              int64_t /*render_time_ms*/) override;
147 
148   int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
149 
150   int Release() override;
151 
152   int Reset() override;
153 
154   const char* ImplementationName() const override;
155 
156  private:
157   int ReturnFrame(const vpx_image_t* img, uint32_t timeStamp);
158 
159   // Memory pool used to share buffers between libvpx and webrtc.
160   Vp9FrameBufferPool frame_buffer_pool_;
161   DecodedImageCallback* decode_complete_callback_;
162   bool inited_;
163   vpx_codec_ctx_t* decoder_;
164   VideoCodec codec_;
165   bool key_frame_required_;
166 };
167 }  // namespace webrtc
168 
169 #endif  // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_VP9_IMPL_H_
170