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(&current_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                                           &current_sps_.level_idc,
305                                           &current_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(&current_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