7 #include "packager/media/formats/mp2t/es_parser_h265.h"
11 #include "packager/base/logging.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/media/base/offset_byte_queue.h"
14 #include "packager/media/base/timestamp.h"
15 #include "packager/media/base/video_stream_info.h"
16 #include "packager/media/codecs/h265_byte_to_unit_stream_converter.h"
17 #include "packager/media/codecs/h265_parser.h"
18 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
19 #include "packager/media/formats/mp2t/mp2t_common.h"
25 EsParserH265::EsParserH265(uint32_t pid,
26 const NewStreamInfoCB& new_stream_info_cb,
27 const EmitSampleCB& emit_sample_cb)
28 : EsParserH26x(Nalu::kH265,
29 std::unique_ptr<H26xByteToUnitStreamConverter>(
30 new H265ByteToUnitStreamConverter()),
33 new_stream_info_cb_(new_stream_info_cb),
34 decoder_config_check_pending_(false),
35 h265_parser_(new H265Parser()) {}
37 EsParserH265::~EsParserH265() {}
39 void EsParserH265::Reset() {
40 DVLOG(1) <<
"EsParserH265::Reset";
41 h265_parser_.reset(
new H265Parser());
42 last_video_decoder_config_ = std::shared_ptr<VideoStreamInfo>();
43 decoder_config_check_pending_ =
false;
44 EsParserH26x::Reset();
47 bool EsParserH265::ProcessNalu(
const Nalu& nalu,
48 VideoSliceInfo* video_slice_info) {
49 video_slice_info->valid =
false;
50 switch (nalu.type()) {
51 case Nalu::H265_AUD: {
52 DVLOG(LOG_LEVEL_ES) <<
"Nalu: AUD";
55 case Nalu::H265_SPS: {
56 DVLOG(LOG_LEVEL_ES) <<
"Nalu: SPS";
58 auto status = h265_parser_->ParseSps(nalu, &sps_id);
59 if (status == H265Parser::kOk)
60 decoder_config_check_pending_ =
true;
61 else if (status == H265Parser::kUnsupportedStream)
63 new_stream_info_cb_.Run(
nullptr);
68 case Nalu::H265_PPS: {
69 DVLOG(LOG_LEVEL_ES) <<
"Nalu: PPS";
71 auto status = h265_parser_->ParsePps(nalu, &pps_id);
72 if (status == H265Parser::kOk) {
73 decoder_config_check_pending_ =
true;
74 }
else if (status == H265Parser::kUnsupportedStream) {
76 new_stream_info_cb_.Run(
nullptr);
79 if (last_video_decoder_config_)
85 if (nalu.is_vcl() && nalu.nuh_layer_id() == 0) {
86 const bool is_key_frame = nalu.type() == Nalu::H265_IDR_W_RADL ||
87 nalu.type() == Nalu::H265_IDR_N_LP;
88 DVLOG(LOG_LEVEL_ES) <<
"Nalu: slice KeyFrame=" << is_key_frame;
90 auto status = h265_parser_->ParseSliceHeader(nalu, &shdr);
91 if (status == H265Parser::kOk) {
92 video_slice_info->valid =
true;
93 video_slice_info->is_key_frame = is_key_frame;
94 video_slice_info->frame_num = 0;
95 video_slice_info->pps_id = shdr.pic_parameter_set_id;
96 }
else if (status == H265Parser::kUnsupportedStream) {
98 new_stream_info_cb_.Run(
nullptr);
102 if (last_video_decoder_config_)
106 DVLOG(LOG_LEVEL_ES) <<
"Nalu: " << nalu.type();
114 bool EsParserH265::UpdateVideoDecoderConfig(
int pps_id) {
116 if (!decoder_config_check_pending_)
119 const H265Pps* pps = h265_parser_->GetPps(pps_id);
127 return last_video_decoder_config_ ==
nullptr;
129 sps = h265_parser_->GetSps(pps->seq_parameter_set_id);
132 decoder_config_check_pending_ =
false;
135 std::vector<uint8_t> decoder_config_record;
136 HEVCDecoderConfigurationRecord decoder_config;
137 if (!stream_converter()->GetDecoderConfigurationRecord(
138 &decoder_config_record) ||
139 !decoder_config.Parse(decoder_config_record)) {
140 DLOG(ERROR) <<
"Failure to construct an HEVCDecoderConfigurationRecord";
144 if (last_video_decoder_config_) {
145 if (last_video_decoder_config_->codec_config() != decoder_config_record) {
151 LOG(WARNING) <<
"H.265 decoder configuration has changed.";
152 last_video_decoder_config_->set_codec_config(decoder_config_record);
157 uint32_t coded_width = 0;
158 uint32_t coded_height = 0;
159 uint32_t pixel_width = 0;
160 uint32_t pixel_height = 0;
161 if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
163 LOG(ERROR) <<
"Failed to parse SPS.";
167 const uint8_t nalu_length_size =
168 H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
169 const H26xStreamFormat stream_format = stream_converter()->stream_format();
170 const FourCC codec_fourcc =
171 stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
174 last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
175 pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH265, stream_format,
176 decoder_config.GetCodecString(codec_fourcc), decoder_config_record.data(),
177 decoder_config_record.size(), coded_width, coded_height, pixel_width,
178 pixel_height, sps->vui_parameters.transfer_characteristics, 0,
179 nalu_length_size, std::string(),
false);
182 new_stream_info_cb_.Run(last_video_decoder_config_);