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
media / gpu / windows / d3d_video_decoder_wrapper.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_WINDOWS_D3D_VIDEO_DECODER_WRAPPER_H_
#define MEDIA_GPU_WINDOWS_D3D_VIDEO_DECODER_WRAPPER_H_
#include <Windows.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <string_view>
#include <vector>
#include "base/containers/span.h"
#include "media/gpu/windows/d3d11_status.h"
#include "media/gpu/windows/scoped_d3d_buffers.h"
namespace media {
class MediaLog;
class D3D11PictureBuffer;
class D3DVideoDecoderWrapper {
public:
enum class BufferType {
kPictureParameters,
kInverseQuantizationMatrix,
kSliceControl,
kBitstream,
};
explicit D3DVideoDecoderWrapper(MediaLog* media_log);
virtual ~D3DVideoDecoderWrapper();
// Get whether single video decoder texture is recommended by the driver.
// Returns whether this operation succeeds.
virtual std::optional<bool> UseSingleTexture() const = 0;
// Clear all internal states.
virtual void Reset() = 0;
// Start a frame and wait for the hardware to be ready for decoding.
virtual bool WaitForFrameBegins(D3D11PictureBuffer* output_picture) = 0;
// Returns whether a buffer of the |type| has already been done in this frame.
// If so, re-copying same data could be avoided.
virtual bool HasPendingBuffer(BufferType type) = 0;
// Submit a slice.
virtual bool SubmitSlice() = 0;
// Submit a frame to start decoding.
virtual bool SubmitDecode() = 0;
ScopedRandomAccessD3DInputBuffer GetPictureParametersBuffer(
uint32_t desired_size);
ScopedRandomAccessD3DInputBuffer GetInverseQuantizationMatrixBuffer(
uint32_t desired_size);
ScopedRandomAccessD3DInputBuffer GetSliceControlBuffer(uint32_t desired_size);
// Get the sequentially writable shared bitstream buffer. The buffer will be
// owned by the D3DVideoDecoderWrapper, shared across multiple calls, and be
// automatically submitted before the slice ends. When the buffer is full, the
// caller should call SubmitSlice(), then call this method for another
// time to get a new unused bitstream buffer.
ScopedSequenceD3DInputBuffer& GetBitstreamBuffer(uint32_t desired_size);
// Append the |start_code| and the |bitstream| to the bitstream buffer. When
// the buffer is full, the |bitstream| will be chopped, then the buffer will
// be submitted, together with the slice data for each (possibly bad) chops.
// The remaining |bitstream| will be append to the new empty buffer.
// The typename |DXVASliceData| could be any short-form slice control
// structure.
// Note: This helper method will do the GetSliceControlBuffer() and
// GetBitstreamBuffer(), you should not do it again before SubmitSlice().
template <typename DXVASliceData>
bool AppendBitstreamAndSliceDataWithStartCode(
base::span<const uint8_t> bitstream,
base::span<const uint8_t> start_code = {});
private:
// Calls SubmitSlice() and GetBitstreamBuffer() to empty `bitstream_buffer_`.
bool SubmitAndGetBitstreamBuffer(size_t needed_size);
protected:
virtual std::unique_ptr<ScopedD3DBuffer> GetBuffer(BufferType type,
uint32_t desired_size) = 0;
// Information that's accumulated during slices and submitted at the end
std::vector<uint8_t> slice_info_bytes_;
std::optional<ScopedSequenceD3DInputBuffer> bitstream_buffer_;
raw_ptr<MediaLog> media_log_ = nullptr;
};
} // namespace media
#endif // MEDIA_GPU_WINDOWS_D3D_VIDEO_DECODER_WRAPPER_H_