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
media / gpu / mac / video_toolbox_h265_accelerator.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_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_
#define MEDIA_GPU_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_
#include <CoreMedia/CoreMedia.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/apple/scoped_cftyperef.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/sequence_checker.h"
#include "media/base/video_types.h"
#include "media/gpu/h265_decoder.h"
#include "media/gpu/mac/video_toolbox_decompression_metadata.h"
#include "media/gpu/media_gpu_export.h"
namespace media {
class MediaLog;
class MEDIA_GPU_EXPORT VideoToolboxH265Accelerator
: public H265Decoder::H265Accelerator {
public:
using DecodeCB = base::RepeatingCallback<void(
base::apple::ScopedCFTypeRef<CMSampleBufferRef>,
VideoToolboxDecompressionSessionMetadata,
scoped_refptr<CodecPicture>)>;
using OutputCB = base::RepeatingCallback<void(scoped_refptr<CodecPicture>)>;
VideoToolboxH265Accelerator(std::unique_ptr<MediaLog> media_log,
DecodeCB decode_cb,
OutputCB output_cb);
~VideoToolboxH265Accelerator() override;
// H265Accelerator implementation.
scoped_refptr<H265Picture> CreateH265Picture() override;
void ProcessVPS(const H265VPS* vps,
base::span<const uint8_t> vps_nalu_data) override;
void ProcessSPS(const H265SPS* sps,
base::span<const uint8_t> sps_nalu_data) override;
void ProcessPPS(const H265PPS* pps,
base::span<const uint8_t> pps_nalu_data) override;
Status SubmitFrameMetadata(
const H265SPS* sps,
const H265PPS* pps,
const H265SliceHeader* slice_hdr,
const H265Picture::Vector& ref_pic_list,
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) 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;
bool OutputPicture(scoped_refptr<H265Picture> pic) override;
void Reset() override;
bool IsChromaSamplingSupported(VideoChromaSampling format) override;
bool IsAlphaLayerSupported() override;
private:
bool ExtractParameterSetData(
const char* parameter_set_name,
const base::flat_set<int>& parameter_set_ids,
const base::flat_map<int, std::vector<uint8_t>>& seen_parameter_set_data,
base::flat_map<int, std::vector<uint8_t>>* active_parameter_set_data_out,
std::vector<const uint8_t*>* parameter_set_data_out,
std::vector<size_t>* parameter_set_size_out);
bool CreateFormat(scoped_refptr<H265Picture> pic);
bool ExtractChangedParameterSetData(
const char* parameter_set_name,
const base::flat_set<int>& parameter_set_ids,
const base::flat_map<int, std::vector<uint8_t>>& seen_parameter_set_data,
base::flat_map<int, std::vector<uint8_t>>* active_parameter_set_data_out,
std::vector<base::span<const uint8_t>>* parameter_set_data_out);
void ResetFrameData();
std::unique_ptr<MediaLog> media_log_;
// Callbacks are called synchronously, which is always re-entrant.
DecodeCB decode_cb_;
OutputCB output_cb_;
// Raw parameter set bytes that have been observed.
base::flat_map<int, std::vector<uint8_t>> seen_vps_data_; // IDs can be 0-16
base::flat_map<int, std::vector<uint8_t>> seen_sps_data_; // IDs can be 0-15
base::flat_map<int, std::vector<uint8_t>> seen_pps_data_; // IDs can be 0-63
// Cached parameter values.
base::flat_set<int> alpha_vps_ids_;
// Raw parameter set bytes that have been sent to the decoder, to compare for
// changes.
base::flat_map<int, std::vector<uint8_t>> active_vps_data_;
base::flat_map<int, std::vector<uint8_t>> active_sps_data_;
base::flat_map<int, std::vector<uint8_t>> active_pps_data_;
base::apple::ScopedCFTypeRef<CMFormatDescriptionRef> active_format_;
VideoToolboxDecompressionSessionMetadata active_session_metadata_;
// Accumulated data for the current frame.
base::flat_set<int> frame_vps_ids_; // Note: there should be exactly one VPS.
base::flat_set<int> frame_sps_ids_;
base::flat_set<int> frame_pps_ids_;
// TODO(367764863) Rewrite to base::raw_span.
RAW_PTR_EXCLUSION std::vector<base::span<const uint8_t>> frame_slice_data_;
uint8_t frame_bit_depth_ = 8;
VideoChromaSampling frame_chroma_sampling_ = VideoChromaSampling::k420;
bool frame_is_keyframe_ = false;
bool frame_has_alpha_ = false;
bool drop_frame_ = false;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace media
#endif // MEDIA_GPU_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_