summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/windows/dxva_video_decode_accelerator_win.h
blob: b863289106c5912f5b06b4cb2bc456b8f2007020 (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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
// Copyright (c) 2012 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_DXVA_VIDEO_DECODE_ACCELERATOR_WIN_H_
#define MEDIA_GPU_WINDOWS_DXVA_VIDEO_DECODE_ACCELERATOR_WIN_H_

#include <d3d11_1.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <initguid.h>
#include <mfidl.h>
#include <stdint.h>
#include <wrl/client.h>

#include <list>
#include <map>
#include <memory>
#include <vector>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/video_color_space.h"
#include "media/gpu/gpu_video_decode_accelerator_helpers.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_com_defs.h"
#include "media/video/video_decode_accelerator.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gl/hdr_metadata_helper_win.h"

interface IMFSample;
interface IDirect3DSurface9;

namespace gl {
class GLContext;
}

namespace gpu {
class GpuDriverBugWorkarounds;
struct GpuPreferences;
}  // namespace gpu

typedef HRESULT(WINAPI* CreateDXGIDeviceManager)(
    UINT* reset_token,
    IMFDXGIDeviceManager** device_manager);

namespace media {
class DXVAPictureBuffer;
class EGLStreamCopyPictureBuffer;
class EGLStreamPictureBuffer;
class MediaLog;
class PbufferPictureBuffer;

class ConfigChangeDetector {
 public:
  virtual ~ConfigChangeDetector();
  virtual bool DetectConfig(const uint8_t* stream, unsigned int size) = 0;
  virtual gfx::Rect current_visible_rect(
      const gfx::Rect& container_visible_rect) const = 0;
  virtual VideoColorSpace current_color_space(
      const VideoColorSpace& container_color_space) const = 0;
  virtual bool IsYUV420() const;
  virtual bool is_vp9_resilient_mode() const;
  bool config_changed() const { return config_changed_; }

 protected:
  // Set to true if we detect a stream configuration change.
  bool config_changed_ = false;
};

// Class to provide a DXVA 2.0 based accelerator using the Microsoft Media
// foundation APIs via the VideoDecodeAccelerator interface.
// This class lives on a single thread and DCHECKs that it is never accessed
// from any other.
class MEDIA_GPU_EXPORT DXVAVideoDecodeAccelerator
    : public VideoDecodeAccelerator {
 public:
  enum State {
    kUninitialized,  // un-initialized.
    kNormal,         // normal playing state.
    kResetting,      // upon received Reset(), before ResetDone()
    kStopped,        // upon output EOS received.
    kFlushing,       // upon flush request received.
  };

  // Does not take ownership of |client| which must outlive |*this|.
  DXVAVideoDecodeAccelerator(
      const GetGLContextCallback& get_gl_context_cb,
      const MakeGLContextCurrentCallback& make_context_current_cb,
      const BindGLImageCallback& bind_image_cb,
      const gpu::GpuDriverBugWorkarounds& workarounds,
      const gpu::GpuPreferences& gpu_preferences,
      MediaLog* media_log);

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

  ~DXVAVideoDecodeAccelerator() override;

  // VideoDecodeAccelerator implementation.
  bool Initialize(const Config& config, Client* client) override;
  void Decode(BitstreamBuffer bitstream) override;
  void Decode(scoped_refptr<DecoderBuffer> buffer,
              int32_t bitstream_id) override;
  void AssignPictureBuffers(const std::vector<PictureBuffer>& buffers) override;
  void ReusePictureBuffer(int32_t picture_buffer_id) override;
  void Flush() override;
  void Reset() override;
  void Destroy() override;
  bool TryToSetupDecodeOnSeparateThread(
      const base::WeakPtr<Client>& decode_client,
      const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
      override;
  GLenum GetSurfaceInternalFormat() const override;
  bool SupportsSharedImagePictureBuffers() const override;

  static VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles(
      const gpu::GpuPreferences& gpu_preferences,
      const gpu::GpuDriverBugWorkarounds& workarounds);

  // Preload dlls required for decoding.
  static void PreSandboxInitialization();

 private:
  friend class DXVAPictureBuffer;
  friend class EGLStreamDelayedCopyPictureBuffer;
  friend class EGLStreamCopyPictureBuffer;
  friend class EGLStreamPictureBuffer;
  friend class PbufferPictureBuffer;
  typedef void* EGLConfig;
  typedef void* EGLSurface;
  typedef std::list<Microsoft::WRL::ComPtr<IMFSample>> PendingInputs;

  // These are used for histograms, so don't change their numeric value (except
  // for kMaxValue as described below).
  enum class PictureBufferMechanism {
    // Copy to either a BGRA8 or FP16 texture using the video processor.
    COPY_TO_RGB = 0,

    // Copy to another NV12 texture that can be used in ANGLE.
    COPY_TO_NV12 = 1,

    // Bind the resulting GLImage to the NV12 texture. If the texture's used
    // in a an overlay than use it directly, otherwise copy it to another NV12
    // texture when necessary.
    DELAYED_COPY_TO_NV12 = 2,

    // Bind the NV12 decoder texture directly to the texture used in ANGLE.
    BIND = 3,

    // For UMA.  Must be the last entry.  It should be initialized to the
    // numerically largest value above; if you add more entries, then please
    // update this to be the last one.
    kMaxValue = BIND
  };

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class DXVALifetimeProgression {
    kInitializeStarted = 0,

    // DX11 init completed successfully.
    kDX11InitializeSucceeded = 1,

    // An error occurred after successful init, split up by whether a frame was
    // delivered to the client yet or not.
    kDX11PlaybackFailedBeforeFirstFrame = 2,
    kDX11PlaybackFailedAfterFirstFrame = 3,

    // Playback succeeded, which requires successful init.
    kDX11PlaybackSucceeded = 4,

    // DX9 variants of the above.
    kDX9InitializeSucceeded = 5,
    kDX9PlaybackFailedBeforeFirstFrame = 6,
    kDX9PlaybackFailedAfterFirstFrame = 7,
    kDX9PlaybackSucceeded = 8,

    // For UMA. Must be the last entry. It should be initialized to the
    // numerically largest value above; if you add more entries, then please
    // update this to the last one.
    kMaxValue = kDX9PlaybackSucceeded
  };

  // Log UMA progression state.
  void AddLifetimeProgressionStage(DXVALifetimeProgression stage);

  // Logs the appropriate PlaybackSucceeded lifetime stage, if we've completed
  // init successfully and not logged an error or playback success since then.
  void AddPlaybackSucceededLifetimeStageIfNeeded();

  // Creates and initializes an instance of the D3D device and the
  // corresponding device manager. The device manager instance is eventually
  // passed to the IMFTransform interface implemented by the decoder.
  bool CreateD3DDevManager();

  // TODO(hubbe): COMMENT
  bool CreateVideoProcessor();

  // Creates and initializes an instance of the DX11 device and the
  // corresponding device manager. The device manager instance is eventually
  // passed to the IMFTransform interface implemented by the decoder.
  bool CreateDX11DevManager();

  // Creates, initializes and sets the media codec types for the decoder.
  bool InitDecoder(VideoCodecProfile profile);

  // Validates whether the decoder supports hardware video acceleration.
  bool CheckDecoderDxvaSupport();

  // Returns information about the input and output streams. This includes
  // alignment information, decoder support flags, minimum sample size, etc.
  bool GetStreamsInfoAndBufferReqs();

  // Registers the input and output media types on the decoder. This includes
  // the expected input and output formats.
  bool SetDecoderMediaTypes();

  // Registers the input media type for the decoder.
  bool SetDecoderInputMediaType();

  // Registers the output media type for the decoder.
  bool SetDecoderOutputMediaType(const GUID& subtype);

  // Passes a command message to the decoder. This includes commands like
  // start of stream, end of stream, flush, drain the decoder, etc.
  bool SendMFTMessage(MFT_MESSAGE_TYPE msg, int32_t param);

  // The bulk of the decoding happens here. This function handles errors,
  // format changes and processes decoded output.
  void DoDecode(const gfx::Rect& visible_rect,
                const gfx::ColorSpace& color_space);

  // Invoked when we have a valid decoded output sample. Retrieves the D3D
  // surface and maintains a copy of it which is passed eventually to the
  // client when we have a picture buffer to copy the surface contents to.
  bool ProcessOutputSample(Microsoft::WRL::ComPtr<IMFSample> sample,
                           const gfx::Rect& visible_rect,
                           const gfx::ColorSpace& color_space);

  // Processes pending output samples by copying them to available picture
  // slots.
  void ProcessPendingSamples();

  // Helper function to notify the accelerator client about the error.
  void StopOnError(VideoDecodeAccelerator::Error error);

  // Transitions the decoder to the uninitialized state. The decoder will stop
  // accepting requests in this state.
  void Invalidate(bool for_config_change = false);

  // Stop and join on the decoder thread.
  void StopDecoderThread();

  // Notifies the client that the input buffer identifed by input_buffer_id has
  // been processed.
  void NotifyInputBufferRead(int input_buffer_id);

  // Notifies the client that the decoder was flushed.
  void NotifyFlushDone();

  // Notifies the client that the decoder was reset.
  void NotifyResetDone();

  // Requests picture buffers from the client.
  void RequestPictureBuffers(int width, int height);

  // Notifies the client about the availability of a picture.
  void NotifyPictureReady(int picture_buffer_id,
                          int input_buffer_id,
                          const gfx::Rect& visible_rect,
                          const gfx::ColorSpace& color_space,
                          bool allow_overlay,
                          std::vector<scoped_refptr<Picture::ScopedSharedImage>>
                              shared_images = {});

  // Sends pending input buffer processed acks to the client if we don't have
  // output samples waiting to be processed.
  void NotifyInputBuffersDropped(const PendingInputs& input_buffers);

  // Decodes pending input buffers.
  void DecodePendingInputBuffers();

  // Helper for handling the Flush operation.
  void FlushInternal();

  // Helper for handling the Decode operation.
  void DecodeInternal(const Microsoft::WRL::ComPtr<IMFSample>& input_sample);

  // Handles mid stream resolution changes.
  void HandleResolutionChanged(int width, int height);

  using OutputBuffers = std::map<int32_t, std::unique_ptr<DXVAPictureBuffer>>;

  // Tells the client to dismiss the stale picture buffers passed in.
  void DismissStaleBuffers(bool force);

  // Called after the client indicates we can recycle a stale picture buffer.
  void DeferredDismissStaleBuffer(int32_t picture_buffer_id);

  // Sets the state of the decoder. Called from the main thread and the decoder
  // thread. The state is changed on the main thread.
  void SetState(State state);

  // Gets the state of the decoder. Can be called from the main thread and
  // the decoder thread. Thread safe.
  State GetState();

  // Starts the thread used for decoding. Returns true on success.
  bool StartDecoderThread();

  // Returns if we have output samples waiting to be processed. We only
  // allow one output sample to be present in the output queue at any given
  // time.
  bool OutputSamplesPresent();

  // Copies the source surface |src_surface| to the destination |dest_surface|.
  // The copying is done on the decoder thread.
  void CopySurface(IDirect3DSurface9* src_surface,
                   IDirect3DSurface9* dest_surface,
                   int picture_buffer_id,
                   int input_buffer_id,
                   const gfx::ColorSpace& color_space);

  // This is a notification that the source surface |src_surface| was copied to
  // the destination |dest_surface|. Received on the main thread.
  void CopySurfaceComplete(IDirect3DSurface9* src_surface,
                           IDirect3DSurface9* dest_surface,
                           int picture_buffer_id,
                           int input_buffer_id);

  void BindPictureBufferToSample(Microsoft::WRL::ComPtr<IMFSample> sample,
                                 int picture_buffer_id,
                                 int input_buffer_id);

  // Copies the source texture |src_texture| to the destination |dest_texture|.
  // The copying is done on the decoder thread.  Returns true on success.
  bool CopyTexture(ID3D11Texture2D* src_texture,
                   ID3D11Texture2D* dest_texture,
                   Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
                   uint64_t keyed_mutex_value,
                   int picture_buffer_id,
                   int input_buffer_id,
                   const gfx::ColorSpace& color_space);

  // Copies the |video_frame| to the destination |dest_texture|.
  void CopyTextureOnDecoderThread(
      ID3D11Texture2D* dest_texture,
      Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
      uint64_t keyed_mutex_value,
      Microsoft::WRL::ComPtr<IMFSample> input_sample,
      int picture_buffer_id,
      int input_buffer_id);

  // Flushes the decoder device to ensure that the decoded surface is copied
  // to the target surface. |iterations| helps to maintain an upper limit on
  // the number of times we try to complete the flush operation.
  void FlushDecoder(int iterations,
                    IDirect3DSurface9* src_surface,
                    IDirect3DSurface9* dest_surface,
                    int picture_buffer_id,
                    int input_buffer_id);

  // Polls to wait for GPU commands to be finished on the picture buffer
  // before reusing it.
  void WaitForOutputBuffer(int32_t picture_buffer_id, int count);

  // Initialize the DX11 video processor.
  // Returns true on success.
  bool InitializeID3D11VideoProcessor(int width,
                                      int height,
                                      const gfx::ColorSpace& color_space);

  // Some devices require HDR metadata.  This will set it if needed, else
  // do nothing.
  void SetDX11ProcessorHDRMetadataIfNeeded();

  // Returns the output video frame dimensions (width, height).
  // |sample| :- This is the output sample containing the video frame.
  // |width| :- The width is returned here.
  // |height| :- The height is returned here.
  // Returns true on success.
  bool GetVideoFrameDimensions(IMFSample* sample, int* width, int* height);

  // Sets the output type on the |transform| to the GUID identified by the
  // the |output_type| parameter. The GUID can be MFVideoFormat_RGB32,
  // MFVideoFormat_ARGB32, MFVideoFormat_NV12, etc.
  // Additionally if the |width| and |height| parameters are non zero, then
  // this function also sets the MF_MT_FRAME_SIZE attribute on the type.
  // Returns true on success.
  bool SetTransformOutputType(IMFTransform* transform,
                              const GUID& output_type,
                              int width,
                              int height);

  // Checks if the resolution, bitrate etc of the stream changed. We do this
  // by keeping track of the SPS/PPS frames and if they change we assume
  // that the configuration changed.
  // Returns S_OK or S_FALSE on success.
  // The |config_changed| parameter is set to true if we detect a change in the
  // stream.
  HRESULT CheckConfigChanged(IMFSample* sample, bool* config_changed);

  // Called when we detect a stream configuration change. We reinitialize the
  // decoder here.
  void ConfigChanged(const Config& config);

  // Sets |support_share_nv12_textures_| to false and updates
  // |num_picture_buffers_requested_|.
  void DisableSharedTextureSupport();

  uint32_t GetTextureTarget() const;

  PictureBufferMechanism GetPictureBufferMechanism() const;
  bool ShouldUseANGLEDevice() const;
  ID3D11Device* D3D11Device() const;

  // To expose client callbacks from VideoDecodeAccelerator.
  VideoDecodeAccelerator::Client* client_;

  Microsoft::WRL::ComPtr<IMFTransform> decoder_;

  Microsoft::WRL::ComPtr<IDirect3D9Ex> d3d9_;
  Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> d3d9_device_ex_;
  Microsoft::WRL::ComPtr<IDirect3DDeviceManager9> device_manager_;
  Microsoft::WRL::ComPtr<IDirect3DQuery9> query_;

  ComD3D11Device d3d11_device_;
  ComD3D11Device angle_device_;
  Microsoft::WRL::ComPtr<IMFDXGIDeviceManager> d3d11_device_manager_;
  Microsoft::WRL::ComPtr<ID3D10Multithread> multi_threaded_;
  ComD3D11DeviceContext d3d11_device_context_;
  ComD3D11Query d3d11_query_;

  ComD3D11VideoDevice video_device_;
  ComD3D11VideoContext video_context_;
  ComD3D11VideoProcessorEnumerator enumerator_;
  ComD3D11VideoProcessor d3d11_processor_;

  int processor_width_ = 0;
  int processor_height_ = 0;

  // Used for lifetime progression logging.  Have we logged that initialization
  // was successful, and nothing since?
  bool already_initialized_ = false;

  Microsoft::WRL::ComPtr<IDirectXVideoProcessorService>
      video_processor_service_;
  Microsoft::WRL::ComPtr<IDirectXVideoProcessor> processor_;
  DXVA2_ProcAmpValues default_procamp_values_;

  // Ideally the reset token would be a stack variable which is used while
  // creating the device manager. However it seems that the device manager
  // holds onto the token and attempts to access it if the underlying device
  // changes.
  // TODO(ananta): This needs to be verified.
  uint32_t dev_manager_reset_token_;

  // Reset token for the DX11 device manager.
  uint32_t dx11_dev_manager_reset_token_;

  // The EGL config to use for decoded frames.
  EGLConfig egl_config_;

  // Current state of the decoder.
  volatile State state_;

  MFT_INPUT_STREAM_INFO input_stream_info_;
  MFT_OUTPUT_STREAM_INFO output_stream_info_;

  // Contains information about a decoded sample.
  struct PendingSampleInfo {
    PendingSampleInfo(int32_t buffer_id,
                      Microsoft::WRL::ComPtr<IMFSample> sample,
                      const gfx::Rect& visible_rect,
                      const gfx::ColorSpace& color_space);
    PendingSampleInfo(const PendingSampleInfo& other);
    ~PendingSampleInfo();

    int32_t input_buffer_id;

    // The target picture buffer id where the frame would be copied to.
    // Defaults to -1.
    int picture_buffer_id;

    gfx::Rect visible_rect;

    // The color space of this picture.
    gfx::ColorSpace color_space;

    Microsoft::WRL::ComPtr<IMFSample> output_sample;
  };

  typedef std::list<PendingSampleInfo> PendingOutputSamples;

  // List of decoded output samples. Protected by |decoder_lock_|.
  PendingOutputSamples pending_output_samples_;

  // This map maintains the picture buffers passed the client for decoding.
  // The key is the picture buffer id.
  OutputBuffers output_picture_buffers_;

  // After a resolution change there may be a few output buffers which have yet
  // to be displayed so they cannot be dismissed immediately. We move them from
  // |output_picture_buffers_| to this map so they may be dismissed once they
  // become available.
  OutputBuffers stale_output_picture_buffers_;

  // Set to true if we requested picture slots from the client.
  bool pictures_requested_;

  // Counter which holds the number of input packets before a successful
  // decode.
  int inputs_before_decode_;

  // Set to true when the drain message is sent to the decoder during a flush
  // operation. Used to ensure the message is only sent once after
  // |pending_input_buffers_| is drained. Protected by |decoder_lock_|.
  bool sent_drain_message_;

  // This is the array size of the D3D11 texture that's output to by the
  // decoder. It's only used for debugging.
  uint32_t output_array_size_ = 0;

  // List of input samples waiting to be processed.
  PendingInputs pending_input_buffers_;

  // Callback to get current GLContext.
  GetGLContextCallback get_gl_context_cb_;
  // Callback to set the correct gl context.
  MakeGLContextCurrentCallback make_context_current_cb_;
  BindGLImageCallback bind_image_cb_;

  // This may be null, e.g. when not using MojoVideoDecoder.
  MediaLog* const media_log_;

  // Which codec we are decoding with hardware acceleration.
  VideoCodec codec_;
  // Thread on which the decoder operations like passing input frames,
  // getting output frames are performed. One instance of this thread
  // is created per decoder instance.
  base::Thread decoder_thread_;

  // Task runner to be used for posting tasks to the decoder thread.
  scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_;

  // Task runner to be used for posting tasks to the main thread.
  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;

  // Used to synchronize access between the decoder thread and the main thread.
  base::Lock decoder_lock_;

  // Disallow rebinding WeakReference ownership to a different thread by
  // keeping a persistent reference. This avoids problems with the
  // thread safety of reaching into this class from multiple threads to
  // attain a WeakPtr.
  base::WeakPtr<DXVAVideoDecodeAccelerator> weak_ptr_;

  // Set to true if we are in the context of a Flush operation. Used to prevent
  // multiple flush done notifications being sent out.
  bool pending_flush_;

  // Use CODECAPI_AVLowLatencyMode.
  bool enable_low_latency_;

  // Supports sharing the decoded NV12 textures with ANGLE
  bool support_share_nv12_textures_;

  // Number of requested picture buffers from the client which are used to hold
  // the decoded samples.
  int num_picture_buffers_requested_;

  // Supports copying the NV12 texture to another NV12 texture to use in
  // ANGLE.
  bool support_copy_nv12_textures_;

  // Supports copying NV12 textures on the main thread to use in ANGLE.
  bool support_delayed_copy_nv12_textures_;

  // Copy video to FP16 scRGB textures.
  bool use_fp16_ = false;

  // True if decoder's output is P010/P016.
  bool decoder_output_p010_or_p016_ = false;

  // When converting YUV to RGB, make sure we tell the blitter about the input
  // color space so that it can convert it correctly.
  bool use_color_info_ = true;

  // Defaults to false. Indicates if we should use D3D or DX11 interfaces for
  // H/W decoding.
  bool use_dx11_;

  // True when using Microsoft's VPx HMFT for decoding.
  bool using_ms_vpx_mft_ = false;

  // True if we should use DXGI keyed mutexes to synchronize between the two
  // contexts.
  bool use_keyed_mutex_;

  // Outputs from the dx11 format converter will be in this color space.
  gfx::ColorSpace dx11_converter_output_color_space_;

  // Set to true if we are sharing ANGLE's device.
  bool using_angle_device_;
  bool using_debug_device_;

  // Enables hardware acceleration for AV1 video decoding.
  const bool enable_accelerated_av1_decode_;

  // Enables hardware acceleration for VP8/VP9 video decoding.
  const bool enable_accelerated_vp8_decode_;
  const bool enable_accelerated_vp9_decode_;

  const bool disallow_vp9_resilient_dxva_decoding_;

  // The media foundation H.264 decoder has problems handling changes like
  // resolution change, bitrate change etc. If we reinitialize the decoder
  // when these changes occur then, the decoder works fine. The
  // H264ConfigChangeDetector class provides functionality to check if the
  // stream configuration changed.
  std::unique_ptr<ConfigChangeDetector> config_change_detector_;

  // Contains the initialization parameters for the video.
  Config config_;

  // Set to true if we are processing a video configuration change.
  bool processing_config_changed_;

  // Contain the visible rect and color space of frames that are currently being
  // fed into the decoder. These may change at a config change.
  gfx::Rect current_visible_rect_;
  VideoColorSpace current_color_space_;

  absl::optional<gl::HDRMetadataHelperWin> hdr_metadata_helper_;
  bool use_empty_video_hdr_metadata_ = false;

  // Have we delivered any decoded frames since the last call to Initialize()?
  bool decoded_any_frames_ = false;

  // WeakPtrFactory for posting tasks back to |this|.
  base::WeakPtrFactory<DXVAVideoDecodeAccelerator> weak_this_factory_{this};

  // Function pointer for the MFCreateDXGIDeviceManager API.
  static CreateDXGIDeviceManager create_dxgi_device_manager_;
};

}  // namespace media

#endif  // MEDIA_GPU_WINDOWS_DXVA_VIDEO_DECODE_ACCELERATOR_WIN_H_