1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/gpu/vaapi/h264_encoder.h"
6
7 #include "base/bits.h"
8 #include "base/stl_util.h"
9 #include "media/gpu/macros.h"
10 #include "media/video/h264_level_limits.h"
11
12 namespace media {
13 namespace {
14 // An IDR every 2048 frames, no I frames and no B frames.
15 // We choose IDR period to equal MaxFrameNum so it must be a power of 2.
16 constexpr int kIDRPeriod = 2048;
17 constexpr int kIPeriod = 0;
18 constexpr int kIPPeriod = 1;
19
20 // The qp range is 0-51 in H264. Select 26 because of the center value.
21 constexpr int kDefaultQP = 26;
22 // Note: Webrtc default values are 24 and 37 respectively, see
23 // h264_encoder_impl.cc.
24 // These values are selected to make our VEA tests pass.
25 constexpr int kMinQP = 24;
26 constexpr int kMaxQP = 42;
27
28 // Subjectively chosen bitrate window size for rate control, in ms.
29 constexpr int kCPBWindowSizeMs = 1500;
30
31 // Subjectively chosen.
32 constexpr size_t kMaxNumReferenceFrames = 4;
33 constexpr size_t kMaxRefIdxL0Size = kMaxNumReferenceFrames;
34 constexpr size_t kMaxRefIdxL1Size = 0;
35
36 // HRD parameters (ch. E.2.2 in H264 spec).
37 constexpr int kBitRateScale = 0; // bit_rate_scale for SPS HRD parameters.
38 constexpr int kCPBSizeScale = 0; // cpb_size_scale for SPS HRD parameters.
39
40 // 4:2:0
41 constexpr int kChromaFormatIDC = 1;
42 } // namespace
43
EncodeParams()44 H264Encoder::EncodeParams::EncodeParams()
45 : idr_period_frames(kIDRPeriod),
46 i_period_frames(kIPeriod),
47 ip_period_frames(kIPPeriod),
48 bitrate_bps(0),
49 framerate(0),
50 cpb_window_size_ms(kCPBWindowSizeMs),
51 cpb_size_bits(0),
52 initial_qp(kDefaultQP),
53 scaling_settings(kMinQP, kMaxQP),
54 max_num_ref_frames(kMaxNumReferenceFrames),
55 max_ref_pic_list0_size(kMaxRefIdxL0Size),
56 max_ref_pic_list1_size(kMaxRefIdxL1Size) {}
57
58 H264Encoder::Accelerator::~Accelerator() = default;
59
H264Encoder(std::unique_ptr<Accelerator> accelerator)60 H264Encoder::H264Encoder(std::unique_ptr<Accelerator> accelerator)
61 : packed_sps_(new H264BitstreamBuffer()),
62 packed_pps_(new H264BitstreamBuffer()),
63 accelerator_(std::move(accelerator)) {}
64
~H264Encoder()65 H264Encoder::~H264Encoder() {
66 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
67 }
68
Initialize(const VideoEncodeAccelerator::Config & config,const AcceleratedVideoEncoder::Config & ave_config)69 bool H264Encoder::Initialize(
70 const VideoEncodeAccelerator::Config& config,
71 const AcceleratedVideoEncoder::Config& ave_config) {
72 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
73 switch (config.output_profile) {
74 case H264PROFILE_BASELINE:
75 case H264PROFILE_MAIN:
76 case H264PROFILE_HIGH:
77 break;
78
79 default:
80 NOTIMPLEMENTED() << "Unsupported profile "
81 << GetProfileName(config.output_profile);
82 return false;
83 }
84
85 if (config.input_visible_size.IsEmpty()) {
86 DVLOGF(1) << "Input visible size could not be empty";
87 return false;
88 }
89 visible_size_ = config.input_visible_size;
90 // For 4:2:0, the pixel sizes have to be even.
91 if ((visible_size_.width() % 2 != 0) || (visible_size_.height() % 2 != 0)) {
92 DVLOGF(1) << "The pixel sizes are not even: " << visible_size_.ToString();
93 return false;
94 }
95 constexpr size_t kH264MacroblockSizeInPixels = 16;
96 coded_size_ = gfx::Size(
97 base::bits::Align(visible_size_.width(), kH264MacroblockSizeInPixels),
98 base::bits::Align(visible_size_.height(), kH264MacroblockSizeInPixels));
99 mb_width_ = coded_size_.width() / kH264MacroblockSizeInPixels;
100 mb_height_ = coded_size_.height() / kH264MacroblockSizeInPixels;
101
102 profile_ = config.output_profile;
103 level_ = config.h264_output_level.value_or(H264SPS::kLevelIDC4p0);
104 uint32_t initial_framerate = config.initial_framerate.value_or(
105 VideoEncodeAccelerator::kDefaultFramerate);
106
107 // Checks if |level_| is valid. If it is invalid, set |level_| to a minimum
108 // level that comforts Table A-1 in H.264 spec with specified bitrate,
109 // framerate and dimension.
110 if (!CheckH264LevelLimits(profile_, level_, config.initial_bitrate,
111 initial_framerate, mb_width_ * mb_height_)) {
112 base::Optional<uint8_t> valid_level =
113 FindValidH264Level(profile_, config.initial_bitrate, initial_framerate,
114 mb_width_ * mb_height_);
115 if (!valid_level) {
116 VLOGF(1) << "Could not find a valid h264 level for"
117 << " profile=" << profile_
118 << " bitrate=" << config.initial_bitrate
119 << " framerate=" << initial_framerate
120 << " size=" << config.input_visible_size.ToString();
121 return false;
122 }
123 level_ = *valid_level;
124 }
125
126 curr_params_.max_ref_pic_list0_size =
127 std::min(kMaxRefIdxL0Size, ave_config.max_num_ref_frames & 0xffff);
128 curr_params_.max_ref_pic_list1_size = std::min(
129 kMaxRefIdxL1Size, (ave_config.max_num_ref_frames >> 16) & 0xffff);
130 curr_params_.max_num_ref_frames =
131 std::min(kMaxNumReferenceFrames, curr_params_.max_ref_pic_list0_size +
132 curr_params_.max_ref_pic_list1_size);
133
134 VideoBitrateAllocation initial_bitrate_allocation;
135 initial_bitrate_allocation.SetBitrate(0, 0, config.initial_bitrate);
136 if (!UpdateRates(initial_bitrate_allocation, initial_framerate))
137 return false;
138
139 UpdateSPS();
140 UpdatePPS();
141
142 return true;
143 }
144
GetCodedSize() const145 gfx::Size H264Encoder::GetCodedSize() const {
146 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
147 DCHECK(!coded_size_.IsEmpty());
148
149 return coded_size_;
150 }
151
GetMaxNumOfRefFrames() const152 size_t H264Encoder::GetMaxNumOfRefFrames() const {
153 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
154
155 return curr_params_.max_num_ref_frames;
156 }
157
GetScalingSettings() const158 ScalingSettings H264Encoder::GetScalingSettings() const {
159 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
160
161 return curr_params_.scaling_settings;
162 }
163
PrepareEncodeJob(EncodeJob * encode_job)164 bool H264Encoder::PrepareEncodeJob(EncodeJob* encode_job) {
165 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
166
167 scoped_refptr<H264Picture> pic = accelerator_->GetPicture(encode_job);
168 DCHECK(pic);
169
170 if (encode_job->IsKeyframeRequested() || encoding_parameters_changed_)
171 frame_num_ = 0;
172
173 pic->frame_num = frame_num_++;
174 frame_num_ %= curr_params_.idr_period_frames;
175
176 if (pic->frame_num == 0) {
177 pic->idr = true;
178 // H264 spec mandates idr_pic_id to differ between two consecutive IDRs.
179 idr_pic_id_ ^= 1;
180 pic->idr_pic_id = idr_pic_id_;
181 ref_pic_list0_.clear();
182
183 encoding_parameters_changed_ = false;
184 encode_job->ProduceKeyframe();
185 }
186
187 if (pic->idr || (curr_params_.i_period_frames != 0 &&
188 pic->frame_num % curr_params_.i_period_frames == 0)) {
189 pic->type = H264SliceHeader::kISlice;
190 } else {
191 pic->type = H264SliceHeader::kPSlice;
192 }
193 if (curr_params_.ip_period_frames != 1) {
194 NOTIMPLEMENTED() << "B frames not implemented";
195 return false;
196 }
197
198 pic->ref = true;
199 pic->pic_order_cnt = pic->frame_num * 2;
200 pic->top_field_order_cnt = pic->pic_order_cnt;
201 pic->pic_order_cnt_lsb = pic->pic_order_cnt;
202
203 DVLOGF(4) << "Starting a new frame, type: " << pic->type
204 << (encode_job->IsKeyframeRequested() ? " (keyframe)" : "")
205 << " frame_num: " << pic->frame_num
206 << " POC: " << pic->pic_order_cnt;
207
208 if (!accelerator_->SubmitFrameParameters(
209 encode_job, curr_params_, current_sps_, current_pps_, pic,
210 ref_pic_list0_, std::list<scoped_refptr<H264Picture>>())) {
211 DVLOGF(1) << "Failed submitting frame parameters";
212 return false;
213 }
214
215 if (pic->type == H264SliceHeader::kISlice) {
216 // We always generate SPS and PPS with I(DR) frame. This will help for Seek
217 // operation on the generated stream.
218 if (!accelerator_->SubmitPackedHeaders(encode_job, packed_sps_,
219 packed_pps_)) {
220 DVLOGF(1) << "Failed submitting keyframe headers";
221 return false;
222 }
223 }
224
225 for (const auto& ref_pic : ref_pic_list0_)
226 encode_job->AddReferencePicture(ref_pic);
227
228 // Store the picture on the list of reference pictures and keep the list
229 // below maximum size, dropping oldest references.
230 if (pic->ref) {
231 ref_pic_list0_.push_front(pic);
232 const size_t max_num_ref_frames =
233 base::checked_cast<size_t>(current_sps_.max_num_ref_frames);
234 while (ref_pic_list0_.size() > max_num_ref_frames)
235 ref_pic_list0_.pop_back();
236 }
237
238 return true;
239 }
240
UpdateRates(const VideoBitrateAllocation & bitrate_allocation,uint32_t framerate)241 bool H264Encoder::UpdateRates(const VideoBitrateAllocation& bitrate_allocation,
242 uint32_t framerate) {
243 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
244
245 uint32_t bitrate = bitrate_allocation.GetSumBps();
246 if (bitrate == 0 || framerate == 0)
247 return false;
248
249 if (curr_params_.bitrate_bps == bitrate &&
250 curr_params_.framerate == framerate) {
251 return true;
252 }
253 VLOGF(2) << "New bitrate: " << bitrate_allocation.GetSumBps()
254 << ", New framerate: " << framerate;
255
256 curr_params_.bitrate_bps = bitrate;
257 curr_params_.framerate = framerate;
258 curr_params_.cpb_size_bits =
259 curr_params_.bitrate_bps * curr_params_.cpb_window_size_ms / 1000;
260
261 bool previous_encoding_parameters_changed = encoding_parameters_changed_;
262
263 UpdateSPS();
264
265 // If SPS parameters are updated, it is required to send the SPS with IDR
266 // frame. However, as a special case, we do not generate IDR frame if only
267 // bitrate and framerate parameters are updated. This is safe because these
268 // will not make a difference on decoder processing. The updated SPS will be
269 // sent a next periodic or requested I(DR) frame. On the other hand, bitrate
270 // and framerate parameter
271 // changes must be affected for encoding. UpdateSPS()+SubmitFrameParameters()
272 // shall apply them to an encoder properly.
273 encoding_parameters_changed_ = previous_encoding_parameters_changed;
274 return true;
275 }
276
UpdateSPS()277 void H264Encoder::UpdateSPS() {
278 memset(¤t_sps_, 0, sizeof(H264SPS));
279
280 // Spec A.2 and A.3.
281 switch (profile_) {
282 case H264PROFILE_BASELINE:
283 // Due to https://crbug.com/345569, we don't distinguish between
284 // constrained and non-constrained baseline profiles. Since many codecs
285 // can't do non-constrained, and constrained is usually what we mean (and
286 // it's a subset of non-constrained), default to it.
287 current_sps_.profile_idc = H264SPS::kProfileIDCConstrainedBaseline;
288 current_sps_.constraint_set0_flag = true;
289 current_sps_.constraint_set1_flag = true;
290 break;
291 case H264PROFILE_MAIN:
292 current_sps_.profile_idc = H264SPS::kProfileIDCMain;
293 current_sps_.constraint_set1_flag = true;
294 break;
295 case H264PROFILE_HIGH:
296 current_sps_.profile_idc = H264SPS::kProfileIDCHigh;
297 break;
298 default:
299 NOTREACHED();
300 return;
301 }
302
303 H264SPS::GetLevelConfigFromProfileLevel(profile_, level_,
304 ¤t_sps_.level_idc,
305 ¤t_sps_.constraint_set3_flag);
306
307 current_sps_.seq_parameter_set_id = 0;
308 current_sps_.chroma_format_idc = kChromaFormatIDC;
309
310 DCHECK_GE(curr_params_.idr_period_frames, 16u)
311 << "idr_period_frames must be >= 16";
312 current_sps_.log2_max_frame_num_minus4 =
313 base::bits::Log2Ceiling(curr_params_.idr_period_frames) - 4;
314 current_sps_.pic_order_cnt_type = 0;
315 current_sps_.log2_max_pic_order_cnt_lsb_minus4 =
316 base::bits::Log2Ceiling(curr_params_.idr_period_frames * 2) - 4;
317 current_sps_.max_num_ref_frames = curr_params_.max_num_ref_frames;
318
319 current_sps_.frame_mbs_only_flag = true;
320
321 DCHECK_GT(mb_width_, 0u);
322 DCHECK_GT(mb_height_, 0u);
323 current_sps_.pic_width_in_mbs_minus1 = mb_width_ - 1;
324 DCHECK(current_sps_.frame_mbs_only_flag);
325 current_sps_.pic_height_in_map_units_minus1 = mb_height_ - 1;
326
327 if (visible_size_ != coded_size_) {
328 // Visible size differs from coded size, fill crop information.
329 current_sps_.frame_cropping_flag = true;
330 DCHECK(!current_sps_.separate_colour_plane_flag);
331 // Spec table 6-1. Only 4:2:0 for now.
332 DCHECK_EQ(current_sps_.chroma_format_idc, 1);
333 // Spec 7.4.2.1.1. Crop is in crop units, which is 2 pixels for 4:2:0.
334 const unsigned int crop_unit_x = 2;
335 const unsigned int crop_unit_y = 2 * (2 - current_sps_.frame_mbs_only_flag);
336 current_sps_.frame_crop_left_offset = 0;
337 current_sps_.frame_crop_right_offset =
338 (coded_size_.width() - visible_size_.width()) / crop_unit_x;
339 current_sps_.frame_crop_top_offset = 0;
340 current_sps_.frame_crop_bottom_offset =
341 (coded_size_.height() - visible_size_.height()) / crop_unit_y;
342 }
343
344 current_sps_.vui_parameters_present_flag = true;
345 current_sps_.timing_info_present_flag = true;
346 current_sps_.num_units_in_tick = 1;
347 current_sps_.time_scale =
348 curr_params_.framerate * 2; // See equation D-2 in spec.
349 current_sps_.fixed_frame_rate_flag = true;
350
351 current_sps_.nal_hrd_parameters_present_flag = true;
352 // H.264 spec ch. E.2.2.
353 current_sps_.cpb_cnt_minus1 = 0;
354 current_sps_.bit_rate_scale = kBitRateScale;
355 current_sps_.cpb_size_scale = kCPBSizeScale;
356 current_sps_.bit_rate_value_minus1[0] =
357 (curr_params_.bitrate_bps >>
358 (kBitRateScale + H264SPS::kBitRateScaleConstantTerm)) -
359 1;
360 current_sps_.cpb_size_value_minus1[0] =
361 (curr_params_.cpb_size_bits >>
362 (kCPBSizeScale + H264SPS::kCPBSizeScaleConstantTerm)) -
363 1;
364 current_sps_.cbr_flag[0] = true;
365 current_sps_.initial_cpb_removal_delay_length_minus_1 =
366 H264SPS::kDefaultInitialCPBRemovalDelayLength - 1;
367 current_sps_.cpb_removal_delay_length_minus1 =
368 H264SPS::kDefaultInitialCPBRemovalDelayLength - 1;
369 current_sps_.dpb_output_delay_length_minus1 =
370 H264SPS::kDefaultDPBOutputDelayLength - 1;
371 current_sps_.time_offset_length = H264SPS::kDefaultTimeOffsetLength;
372 current_sps_.low_delay_hrd_flag = false;
373
374 GeneratePackedSPS();
375 encoding_parameters_changed_ = true;
376 }
377
UpdatePPS()378 void H264Encoder::UpdatePPS() {
379 memset(¤t_pps_, 0, sizeof(H264PPS));
380
381 current_pps_.seq_parameter_set_id = current_sps_.seq_parameter_set_id;
382 current_pps_.pic_parameter_set_id = 0;
383
384 current_pps_.entropy_coding_mode_flag =
385 current_sps_.profile_idc >= H264SPS::kProfileIDCMain;
386
387 DCHECK_GT(curr_params_.max_ref_pic_list0_size, 0u);
388 current_pps_.num_ref_idx_l0_default_active_minus1 =
389 curr_params_.max_ref_pic_list0_size - 1;
390 current_pps_.num_ref_idx_l1_default_active_minus1 =
391 curr_params_.max_ref_pic_list1_size > 0
392 ? curr_params_.max_ref_pic_list1_size - 1
393 : curr_params_.max_ref_pic_list1_size;
394 DCHECK_LE(curr_params_.initial_qp, 51);
395 current_pps_.pic_init_qp_minus26 = curr_params_.initial_qp - 26;
396 current_pps_.deblocking_filter_control_present_flag = true;
397 current_pps_.transform_8x8_mode_flag =
398 (current_sps_.profile_idc == H264SPS::kProfileIDCHigh);
399
400 GeneratePackedPPS();
401 encoding_parameters_changed_ = true;
402 }
403
GeneratePackedSPS()404 void H264Encoder::GeneratePackedSPS() {
405 packed_sps_->Reset();
406
407 packed_sps_->BeginNALU(H264NALU::kSPS, 3);
408
409 packed_sps_->AppendBits(8, current_sps_.profile_idc);
410 packed_sps_->AppendBool(current_sps_.constraint_set0_flag);
411 packed_sps_->AppendBool(current_sps_.constraint_set1_flag);
412 packed_sps_->AppendBool(current_sps_.constraint_set2_flag);
413 packed_sps_->AppendBool(current_sps_.constraint_set3_flag);
414 packed_sps_->AppendBool(current_sps_.constraint_set4_flag);
415 packed_sps_->AppendBool(current_sps_.constraint_set5_flag);
416 packed_sps_->AppendBits(2, 0); // reserved_zero_2bits
417 packed_sps_->AppendBits(8, current_sps_.level_idc);
418 packed_sps_->AppendUE(current_sps_.seq_parameter_set_id);
419
420 if (current_sps_.profile_idc == H264SPS::kProfileIDCHigh) {
421 packed_sps_->AppendUE(current_sps_.chroma_format_idc);
422 if (current_sps_.chroma_format_idc == 3)
423 packed_sps_->AppendBool(current_sps_.separate_colour_plane_flag);
424 packed_sps_->AppendUE(current_sps_.bit_depth_luma_minus8);
425 packed_sps_->AppendUE(current_sps_.bit_depth_chroma_minus8);
426 packed_sps_->AppendBool(current_sps_.qpprime_y_zero_transform_bypass_flag);
427 packed_sps_->AppendBool(current_sps_.seq_scaling_matrix_present_flag);
428 CHECK(!current_sps_.seq_scaling_matrix_present_flag);
429 }
430
431 packed_sps_->AppendUE(current_sps_.log2_max_frame_num_minus4);
432 packed_sps_->AppendUE(current_sps_.pic_order_cnt_type);
433 if (current_sps_.pic_order_cnt_type == 0)
434 packed_sps_->AppendUE(current_sps_.log2_max_pic_order_cnt_lsb_minus4);
435 else if (current_sps_.pic_order_cnt_type == 1)
436 NOTREACHED();
437
438 packed_sps_->AppendUE(current_sps_.max_num_ref_frames);
439 packed_sps_->AppendBool(current_sps_.gaps_in_frame_num_value_allowed_flag);
440 packed_sps_->AppendUE(current_sps_.pic_width_in_mbs_minus1);
441 packed_sps_->AppendUE(current_sps_.pic_height_in_map_units_minus1);
442
443 packed_sps_->AppendBool(current_sps_.frame_mbs_only_flag);
444 if (!current_sps_.frame_mbs_only_flag)
445 packed_sps_->AppendBool(current_sps_.mb_adaptive_frame_field_flag);
446
447 packed_sps_->AppendBool(current_sps_.direct_8x8_inference_flag);
448
449 packed_sps_->AppendBool(current_sps_.frame_cropping_flag);
450 if (current_sps_.frame_cropping_flag) {
451 packed_sps_->AppendUE(current_sps_.frame_crop_left_offset);
452 packed_sps_->AppendUE(current_sps_.frame_crop_right_offset);
453 packed_sps_->AppendUE(current_sps_.frame_crop_top_offset);
454 packed_sps_->AppendUE(current_sps_.frame_crop_bottom_offset);
455 }
456
457 packed_sps_->AppendBool(current_sps_.vui_parameters_present_flag);
458 if (current_sps_.vui_parameters_present_flag) {
459 packed_sps_->AppendBool(false); // aspect_ratio_info_present_flag
460 packed_sps_->AppendBool(false); // overscan_info_present_flag
461 packed_sps_->AppendBool(false); // video_signal_type_present_flag
462 packed_sps_->AppendBool(false); // chroma_loc_info_present_flag
463
464 packed_sps_->AppendBool(current_sps_.timing_info_present_flag);
465 if (current_sps_.timing_info_present_flag) {
466 packed_sps_->AppendBits(32, current_sps_.num_units_in_tick);
467 packed_sps_->AppendBits(32, current_sps_.time_scale);
468 packed_sps_->AppendBool(current_sps_.fixed_frame_rate_flag);
469 }
470
471 packed_sps_->AppendBool(current_sps_.nal_hrd_parameters_present_flag);
472 if (current_sps_.nal_hrd_parameters_present_flag) {
473 packed_sps_->AppendUE(current_sps_.cpb_cnt_minus1);
474 packed_sps_->AppendBits(4, current_sps_.bit_rate_scale);
475 packed_sps_->AppendBits(4, current_sps_.cpb_size_scale);
476 CHECK_LT(base::checked_cast<size_t>(current_sps_.cpb_cnt_minus1),
477 base::size(current_sps_.bit_rate_value_minus1));
478 for (int i = 0; i <= current_sps_.cpb_cnt_minus1; ++i) {
479 packed_sps_->AppendUE(current_sps_.bit_rate_value_minus1[i]);
480 packed_sps_->AppendUE(current_sps_.cpb_size_value_minus1[i]);
481 packed_sps_->AppendBool(current_sps_.cbr_flag[i]);
482 }
483 packed_sps_->AppendBits(
484 5, current_sps_.initial_cpb_removal_delay_length_minus_1);
485 packed_sps_->AppendBits(5, current_sps_.cpb_removal_delay_length_minus1);
486 packed_sps_->AppendBits(5, current_sps_.dpb_output_delay_length_minus1);
487 packed_sps_->AppendBits(5, current_sps_.time_offset_length);
488 }
489
490 packed_sps_->AppendBool(false); // vcl_hrd_parameters_flag
491 if (current_sps_.nal_hrd_parameters_present_flag)
492 packed_sps_->AppendBool(current_sps_.low_delay_hrd_flag);
493
494 packed_sps_->AppendBool(false); // pic_struct_present_flag
495 packed_sps_->AppendBool(true); // bitstream_restriction_flag
496
497 packed_sps_->AppendBool(false); // motion_vectors_over_pic_boundaries_flag
498 packed_sps_->AppendUE(2); // max_bytes_per_pic_denom
499 packed_sps_->AppendUE(1); // max_bits_per_mb_denom
500 packed_sps_->AppendUE(16); // log2_max_mv_length_horizontal
501 packed_sps_->AppendUE(16); // log2_max_mv_length_vertical
502
503 // Explicitly set max_num_reorder_frames to 0 to allow the decoder to
504 // output pictures early.
505 packed_sps_->AppendUE(0); // max_num_reorder_frames
506
507 // The value of max_dec_frame_buffering shall be greater than or equal to
508 // max_num_ref_frames.
509 const unsigned int max_dec_frame_buffering =
510 current_sps_.max_num_ref_frames;
511 packed_sps_->AppendUE(max_dec_frame_buffering);
512 }
513
514 packed_sps_->FinishNALU();
515 }
516
GeneratePackedPPS()517 void H264Encoder::GeneratePackedPPS() {
518 packed_pps_->Reset();
519
520 packed_pps_->BeginNALU(H264NALU::kPPS, 3);
521
522 packed_pps_->AppendUE(current_pps_.pic_parameter_set_id);
523 packed_pps_->AppendUE(current_pps_.seq_parameter_set_id);
524 packed_pps_->AppendBool(current_pps_.entropy_coding_mode_flag);
525 packed_pps_->AppendBool(
526 current_pps_.bottom_field_pic_order_in_frame_present_flag);
527 CHECK_EQ(current_pps_.num_slice_groups_minus1, 0);
528 packed_pps_->AppendUE(current_pps_.num_slice_groups_minus1);
529
530 packed_pps_->AppendUE(current_pps_.num_ref_idx_l0_default_active_minus1);
531 packed_pps_->AppendUE(current_pps_.num_ref_idx_l1_default_active_minus1);
532
533 packed_pps_->AppendBool(current_pps_.weighted_pred_flag);
534 packed_pps_->AppendBits(2, current_pps_.weighted_bipred_idc);
535
536 packed_pps_->AppendSE(current_pps_.pic_init_qp_minus26);
537 packed_pps_->AppendSE(current_pps_.pic_init_qs_minus26);
538 packed_pps_->AppendSE(current_pps_.chroma_qp_index_offset);
539
540 packed_pps_->AppendBool(current_pps_.deblocking_filter_control_present_flag);
541 packed_pps_->AppendBool(current_pps_.constrained_intra_pred_flag);
542 packed_pps_->AppendBool(current_pps_.redundant_pic_cnt_present_flag);
543
544 packed_pps_->AppendBool(current_pps_.transform_8x8_mode_flag);
545 packed_pps_->AppendBool(current_pps_.pic_scaling_matrix_present_flag);
546 DCHECK(!current_pps_.pic_scaling_matrix_present_flag);
547 packed_pps_->AppendSE(current_pps_.second_chroma_qp_index_offset);
548
549 packed_pps_->FinishNALU();
550 }
551
552 } // namespace media
553