summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/windows/d3d11_h265_accelerator.h
blob: f094b9c6a05a9769a52c5f02902f698e182b8804 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// Copyright 2022 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 MEDIA_GPU_WINDOWS_D3D11_H265_ACCELERATOR_H_
#define MEDIA_GPU_WINDOWS_D3D11_H265_ACCELERATOR_H_

#include <d3d11_1.h>
#include <d3d9.h>
#include <dxva.h>
#include <wrl/client.h>

#include <vector>

#include "base/memory/raw_ptr.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "media/base/video_frame.h"
#include "media/base/win/mf_helpers.h"
#include "media/gpu/h265_decoder.h"
#include "media/gpu/h265_dpb.h"
#include "media/gpu/windows/d3d11_com_defs.h"
#include "media/gpu/windows/d3d11_status.h"
#include "media/gpu/windows/d3d11_video_context_wrapper.h"
#include "media/gpu/windows/d3d11_video_decoder_client.h"
#include "media/video/picture.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"

namespace media {

// Maximum of valid DXVA_PicEntry_HEVC entries in RefPicList
constexpr unsigned kMaxRefPicListSize = 15;

class D3D11H265Accelerator;
class MediaLog;

// Picture Parameters DXVA buffer struct for Rext/Scc is not specified in DXVA
// spec. The below structures come from Intel platform DDI definition, so they
// are currently Intel specific.
// For NVidia and AMD platforms supporting HEVC Rext & Scc, it is expected
// the picture param information included in below structures is sufficient
// for underlying drivers supporting range extension/Scc.
#pragma pack(push, 1)
typedef struct {
  DXVA_PicParams_HEVC main;

  // HEVC Range Extension. Fields are named the same as in HEVC spec.
  union {
    struct {
      UINT32 transform_skip_rotation_enabled_flag : 1;
      UINT32 transform_skip_context_enabled_flag : 1;
      UINT32 implicit_rdpcm_enabled_flag : 1;
      UINT32 explicit_rdpcm_enabled_flag : 1;
      UINT32 extended_precision_processing_flag : 1;
      UINT32 intra_smoothing_disabled_flag : 1;
      UINT32 high_precision_offsets_enabled_flag : 1;
      UINT32 persistent_rice_adaptation_enabled_flag : 1;
      UINT32 cabac_bypass_alignment_enabled_flag : 1;
      UINT32 cross_component_prediction_enabled_flag : 1;
      UINT32 chroma_qp_offset_list_enabled_flag : 1;
      // Indicates if luma bit depth equals to 16. If its value is 1, the
      // corresponding bit_depth_luma_minus8 must be set to 0.
      UINT32 BitDepthLuma16 : 1;
      // Indicates if chroma bit depth equals to 16. If its value is 1, the
      // corresponding bit_depth_chroma_minus8 must be set to 0.
      UINT32 BitDepthChroma16 : 1;
      UINT32 ReservedBits8 : 19;
    };
    UINT32 dwRangeExtensionFlags;
  };

  UCHAR diff_cu_chroma_qp_offset_depth;    // [0..3]
  UCHAR chroma_qp_offset_list_len_minus1;  // [0..5]
  UCHAR log2_sao_offset_scale_luma;        // [0..6]
  UCHAR log2_sao_offset_scale_chroma;      // [0..6]
  UCHAR log2_max_transform_skip_block_size_minus2;
  CHAR cb_qp_offset_list[6];  // [-12..12]
  CHAR cr_qp_offset_list[6];  // [-12..12]
} DXVA_PicParams_HEVC_Rext;

typedef struct {
  DXVA_PicParams_HEVC_Rext main_rext;

  // HEVC Screen Content Coding. Fields are named the same as in HEVC spec.
  union {
    struct {
      UINT32 pps_curr_pic_ref_enabled_flag : 1;
      UINT32 palette_mode_enabled_flag : 1;
      UINT32 motion_vector_resolution_control_idc : 2;
      UINT32 intra_boundary_filtering_disabled_flag : 1;
      UINT32 residual_adaptive_coloour_transform_enabled_flag : 1;
      UINT32 pps_slice_act_qp_offsets_present_flag : 1;
      UINT32 ReservedBits9 : 25;
    };
    UINT dwSccExtensionFlags;
  };

  UCHAR palette_max_size;                  // [0..64]
  UCHAR delta_palette_max_predictor_size;  // [0..128]
  UCHAR PredictorPaletteSize;              // [0..127]
  USHORT PredictorPaletteEntries[3][128];
  CHAR pps_act_y_qp_offset_plus5;   // [-7..17]
  CHAR pps_act_cb_qp_offset_plus5;  // [-7..17]
  CHAR pps_act_cr_qp_offset_plus3;  // [-9..15]
} DXVA_PicParams_HEVC_SCC;
#pragma pack(pop)

class D3D11H265Accelerator : public H265Decoder::H265Accelerator {
 public:
  D3D11H265Accelerator(D3D11VideoDecoderClient* client,
                       MediaLog* media_log,
                       ComD3D11VideoDevice video_device,
                       std::unique_ptr<VideoContextWrapper> video_context);

  D3D11H265Accelerator(const D3D11H265Accelerator&) = delete;
  D3D11H265Accelerator& operator=(const D3D11H265Accelerator&) = delete;

  ~D3D11H265Accelerator() override;

  // H265Decoder::H265Accelerator implementation.
  scoped_refptr<H265Picture> CreateH265Picture() override;
  Status SubmitFrameMetadata(const H265SPS* sps,
                             const H265PPS* pps,
                             const H265SliceHeader* slice_hdr,
                             const H265Picture::Vector& ref_pic_list,
                             scoped_refptr<H265Picture> pic) override;
  Status SubmitSlice(const H265SPS* sps,
                     const H265PPS* pps,
                     const H265SliceHeader* slice_hdr,
                     const H265Picture::Vector& ref_pic_list0,
                     const H265Picture::Vector& ref_pic_list1,
                     const H265Picture::Vector& ref_pic_set_lt_curr,
                     const H265Picture::Vector& ref_pic_set_st_curr_after,
                     const H265Picture::Vector& ref_pic_set_st_curr_before,
                     scoped_refptr<H265Picture> pic,
                     const uint8_t* data,
                     size_t size,
                     const std::vector<SubsampleEntry>& subsamples) override;
  Status SubmitDecode(scoped_refptr<H265Picture> pic) override;
  void Reset() override;
  bool OutputPicture(scoped_refptr<H265Picture> pic) override;
  bool IsChromaSamplingSupported(VideoChromaSampling chroma_sampling) override;

 private:
  bool SubmitSliceData();
  bool RetrieveBitstreamBuffer();

  // Gets a pic params struct with the constant fields set.
  void FillPicParamsWithConstants(DXVA_PicParams_HEVC_Rext* pic_param);

  // Populate the pic params with fields from the SPS structure.
  void PicParamsFromSPS(DXVA_PicParams_HEVC_Rext* pic_param,
                        const H265SPS* sps);

  // Populate the pic params with fields from the PPS structure.
  void PicParamsFromPPS(DXVA_PicParams_HEVC_Rext* pic_param,
                        const H265PPS* pps);

  // Populate the pic params with fields from the slice header structure.
  void PicParamsFromSliceHeader(DXVA_PicParams_HEVC_Rext* pic_param,
                                const H265SPS* sps,
                                const H265SliceHeader* slice_hdr);

  // Populate the pic params with fields from the picture passed in.
  void PicParamsFromPic(DXVA_PicParams_HEVC_Rext* pic_param,
                        D3D11H265Picture* pic);

  // Populate the pic params with fields from ref_pic_set_lt_curr,
  // ref_pic_set_st_curr_after and ref_pic_set_st_curr_before
  bool PicParamsFromRefLists(
      DXVA_PicParams_HEVC_Rext* pic_param,
      const H265Picture::Vector& ref_pic_set_lt_curr,
      const H265Picture::Vector& ref_pic_set_st_curr_after,
      const H265Picture::Vector& ref_pic_set_st_curr_before);

  void SetVideoDecoder(ComD3D11VideoDecoder video_decoder);

  // Record a failure to DVLOG and |media_log_|.
  void RecordFailure(const std::string& reason,
                     D3D11Status::Codes code,
                     HRESULT hr = S_OK) const;
  void RecordFailure(D3D11Status error) const;

  raw_ptr<D3D11VideoDecoderClient> client_;
  raw_ptr<MediaLog> media_log_ = nullptr;

  ComD3D11VideoDecoder video_decoder_;
  ComD3D11VideoDevice video_device_;
  std::unique_ptr<VideoContextWrapper> video_context_;

  // This information set at the beginning of a frame and saved for processing
  // all the slices.
  DXVA_PicEntry_HEVC ref_frame_list_[kMaxRefPicListSize];
  int ref_frame_pocs_[kMaxRefPicListSize];
  base::flat_map<int, int> poc_index_into_ref_pic_list_;
  bool use_scaling_lists_ = false;
  // If current stream is encoded with range extension profile.
  bool is_rext_ = false;

  // Information that's accumulated during slices and submitted at the end
  std::vector<DXVA_Slice_HEVC_Short> slice_info_;
  size_t current_offset_ = 0;
  size_t bitstream_buffer_size_ = 0;
  raw_ptr<uint8_t> bitstream_buffer_bytes_ = nullptr;

  // For HEVC this number needs to be larger than 1 and different
  // in each call to Execute().
  int current_status_report_feedback_num_ = 1;

  // This contains the subsamples (clear and encrypted) of the slice data
  // in D3D11_VIDEO_DECODER_BUFFER_BITSTREAM buffer.
  std::vector<D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK> subsamples_;
  // IV for the current frame.
  std::vector<uint8_t> frame_iv_;
};

}  // namespace media

#endif  // MEDIA_GPU_WINDOWS_D3D11_H265_ACCELERATOR_H_