5 #include "packager/media/formats/mp2t/es_parser_h264.h"
9 #include "packager/base/logging.h"
10 #include "packager/media/base/media_sample.h"
11 #include "packager/media/base/timestamp.h"
12 #include "packager/media/base/video_stream_info.h"
13 #include "packager/media/codecs/avc_decoder_configuration_record.h"
14 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
15 #include "packager/media/codecs/h264_parser.h"
16 #include "packager/media/formats/mp2t/mp2t_common.h"
22 EsParserH264::EsParserH264(uint32_t pid,
23 const NewStreamInfoCB& new_stream_info_cb,
24 const EmitSampleCB& emit_sample_cb)
25 : EsParserH26x(Nalu::kH264,
26 std::unique_ptr<H26xByteToUnitStreamConverter>(
27 new H264ByteToUnitStreamConverter()),
30 new_stream_info_cb_(new_stream_info_cb),
31 decoder_config_check_pending_(false),
32 h264_parser_(new H264Parser()) {}
34 EsParserH264::~EsParserH264() {}
36 void EsParserH264::Reset() {
37 DVLOG(1) <<
"EsParserH264::Reset";
38 h264_parser_.reset(
new H264Parser());
39 last_video_decoder_config_ = std::shared_ptr<StreamInfo>();
40 decoder_config_check_pending_ =
false;
41 EsParserH26x::Reset();
44 bool EsParserH264::ProcessNalu(
const Nalu& nalu,
45 VideoSliceInfo* video_slice_info) {
46 video_slice_info->valid =
false;
47 switch (nalu.type()) {
48 case Nalu::H264_AUD: {
49 DVLOG(LOG_LEVEL_ES) <<
"Nalu: AUD";
52 case Nalu::H264_SPS: {
53 DVLOG(LOG_LEVEL_ES) <<
"Nalu: SPS";
55 auto status = h264_parser_->ParseSps(nalu, &sps_id);
56 if (status == H264Parser::kOk)
57 decoder_config_check_pending_ =
true;
58 else if (status == H264Parser::kUnsupportedStream)
60 new_stream_info_cb_.Run(
nullptr);
65 case Nalu::H264_PPS: {
66 DVLOG(LOG_LEVEL_ES) <<
"Nalu: PPS";
68 auto status = h264_parser_->ParsePps(nalu, &pps_id);
69 if (status == H264Parser::kOk) {
70 decoder_config_check_pending_ =
true;
71 }
else if (status == H264Parser::kUnsupportedStream) {
73 new_stream_info_cb_.Run(
nullptr);
76 if (last_video_decoder_config_)
81 case Nalu::H264_IDRSlice:
82 case Nalu::H264_NonIDRSlice: {
83 const bool is_key_frame = (nalu.type() == Nalu::H264_IDRSlice);
84 DVLOG(LOG_LEVEL_ES) <<
"Nalu: slice IDR=" << is_key_frame;
86 auto status = h264_parser_->ParseSliceHeader(nalu, &shdr);
87 if (status == H264Parser::kOk) {
88 video_slice_info->valid =
true;
89 video_slice_info->is_key_frame = is_key_frame;
90 video_slice_info->frame_num = shdr.frame_num;
91 video_slice_info->pps_id = shdr.pic_parameter_set_id;
92 }
else if (status == H264Parser::kUnsupportedStream) {
94 new_stream_info_cb_.Run(
nullptr);
98 if (last_video_decoder_config_)
104 DVLOG(LOG_LEVEL_ES) <<
"Nalu: " << nalu.type();
111 bool EsParserH264::UpdateVideoDecoderConfig(
int pps_id) {
113 if (!decoder_config_check_pending_)
116 const H264Pps* pps = h264_parser_->GetPps(pps_id);
124 return last_video_decoder_config_ ==
nullptr;
126 sps = h264_parser_->GetSps(pps->seq_parameter_set_id);
129 decoder_config_check_pending_ =
false;
132 std::vector<uint8_t> decoder_config_record;
133 if (!stream_converter()->GetDecoderConfigurationRecord(
134 &decoder_config_record)) {
135 DLOG(ERROR) <<
"Failure to construct an AVCDecoderConfigurationRecord";
139 if (last_video_decoder_config_) {
140 if (last_video_decoder_config_->codec_config() != decoder_config_record) {
146 LOG(WARNING) <<
"H.264 decoder configuration has changed.";
147 last_video_decoder_config_->set_codec_config(decoder_config_record);
152 uint32_t coded_width = 0;
153 uint32_t coded_height = 0;
154 uint32_t pixel_width = 0;
155 uint32_t pixel_height = 0;
156 if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
158 LOG(ERROR) <<
"Failed to parse SPS.";
162 const uint8_t nalu_length_size =
163 H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
164 const H26xStreamFormat stream_format = stream_converter()->stream_format();
165 const FourCC codec_fourcc =
166 stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
169 last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
170 pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, stream_format,
172 codec_fourcc, decoder_config_record[1], decoder_config_record[2],
173 decoder_config_record[3]),
174 decoder_config_record.data(), decoder_config_record.size(), coded_width,
175 coded_height, pixel_width, pixel_height, sps->transfer_characteristics, 0,
176 nalu_length_size, std::string(),
false);
177 DVLOG(1) <<
"Profile IDC: " << sps->profile_idc;
178 DVLOG(1) <<
"Level IDC: " << sps->level_idc;
179 DVLOG(1) <<
"log2_max_frame_num_minus4: " << sps->log2_max_frame_num_minus4;
182 new_stream_info_cb_.Run(last_video_decoder_config_);