Line data Source code
1 : /*
2 : * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/common_video/h264/sps_parser.h"
12 :
13 : #include <memory>
14 :
15 : #include "webrtc/common_video/h264/h264_common.h"
16 : #include "webrtc/base/bitbuffer.h"
17 : #include "webrtc/base/bytebuffer.h"
18 : #include "webrtc/base/logging.h"
19 :
20 : typedef rtc::Optional<webrtc::SpsParser::SpsState> OptionalSps;
21 :
22 : #define RETURN_EMPTY_ON_FAIL(x) \
23 : if (!(x)) { \
24 : return OptionalSps(); \
25 : }
26 :
27 : namespace webrtc {
28 :
29 : // General note: this is based off the 02/2014 version of the H.264 standard.
30 : // You can find it on this page:
31 : // http://www.itu.int/rec/T-REC-H.264
32 :
33 : // Unpack RBSP and parse SPS state from the supplied buffer.
34 0 : rtc::Optional<SpsParser::SpsState> SpsParser::ParseSps(const uint8_t* data,
35 : size_t length) {
36 0 : std::unique_ptr<rtc::Buffer> unpacked_buffer = H264::ParseRbsp(data, length);
37 0 : rtc::BitBuffer bit_buffer(unpacked_buffer->data(), unpacked_buffer->size());
38 0 : return ParseSpsUpToVui(&bit_buffer);
39 : }
40 :
41 0 : rtc::Optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
42 : rtc::BitBuffer* buffer) {
43 : // Now, we need to use a bit buffer to parse through the actual AVC SPS
44 : // format. See Section 7.3.2.1.1 ("Sequence parameter set data syntax") of the
45 : // H.264 standard for a complete description.
46 : // Since we only care about resolution, we ignore the majority of fields, but
47 : // we still have to actively parse through a lot of the data, since many of
48 : // the fields have variable size.
49 : // We're particularly interested in:
50 : // chroma_format_idc -> affects crop units
51 : // pic_{width,height}_* -> resolution of the frame in macroblocks (16x16).
52 : // frame_crop_*_offset -> crop information
53 :
54 0 : SpsState sps;
55 :
56 : // The golomb values we have to read, not just consume.
57 : uint32_t golomb_ignored;
58 :
59 : // chroma_format_idc will be ChromaArrayType if separate_colour_plane_flag is
60 : // 0. It defaults to 1, when not specified.
61 0 : uint32_t chroma_format_idc = 1;
62 :
63 : // profile_idc: u(8). We need it to determine if we need to read/skip chroma
64 : // formats.
65 : uint8_t profile_idc;
66 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadUInt8(&profile_idc));
67 : // constraint_set0_flag through constraint_set5_flag + reserved_zero_2bits
68 : // 1 bit each for the flags + 2 bits = 8 bits = 1 byte.
69 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
70 : // level_idc: u(8)
71 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
72 : // seq_parameter_set_id: ue(v)
73 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.id));
74 0 : sps.separate_colour_plane_flag = 0;
75 : // See if profile_idc has chroma format information.
76 0 : if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
77 0 : profile_idc == 244 || profile_idc == 44 || profile_idc == 83 ||
78 0 : profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ||
79 0 : profile_idc == 138 || profile_idc == 139 || profile_idc == 134) {
80 : // chroma_format_idc: ue(v)
81 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&chroma_format_idc));
82 0 : if (chroma_format_idc == 3) {
83 : // separate_colour_plane_flag: u(1)
84 0 : RETURN_EMPTY_ON_FAIL(
85 : buffer->ReadBits(&sps.separate_colour_plane_flag, 1));
86 : }
87 : // bit_depth_luma_minus8: ue(v)
88 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
89 : // bit_depth_chroma_minus8: ue(v)
90 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
91 : // qpprime_y_zero_transform_bypass_flag: u(1)
92 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
93 : // seq_scaling_matrix_present_flag: u(1)
94 : uint32_t seq_scaling_matrix_present_flag;
95 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&seq_scaling_matrix_present_flag, 1));
96 0 : if (seq_scaling_matrix_present_flag) {
97 : // seq_scaling_list_present_flags. Either 8 or 12, depending on
98 : // chroma_format_idc.
99 : uint32_t seq_scaling_list_present_flags;
100 0 : if (chroma_format_idc != 3) {
101 0 : RETURN_EMPTY_ON_FAIL(
102 : buffer->ReadBits(&seq_scaling_list_present_flags, 8));
103 : } else {
104 0 : RETURN_EMPTY_ON_FAIL(
105 : buffer->ReadBits(&seq_scaling_list_present_flags, 12));
106 : }
107 : // We don't support reading the sequence scaling list, and we don't really
108 : // see/use them in practice, so we'll just reject the full sps if we see
109 : // any provided.
110 0 : if (seq_scaling_list_present_flags > 0) {
111 0 : LOG(LS_WARNING) << "SPS contains scaling lists, which are unsupported.";
112 0 : return OptionalSps();
113 : }
114 : }
115 : }
116 : // log2_max_frame_num_minus4: ue(v)
117 0 : RETURN_EMPTY_ON_FAIL(
118 : buffer->ReadExponentialGolomb(&sps.log2_max_frame_num_minus4));
119 : // pic_order_cnt_type: ue(v)
120 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.pic_order_cnt_type));
121 0 : if (sps.pic_order_cnt_type == 0) {
122 : // log2_max_pic_order_cnt_lsb_minus4: ue(v)
123 0 : RETURN_EMPTY_ON_FAIL(
124 : buffer->ReadExponentialGolomb(&sps.log2_max_pic_order_cnt_lsb_minus4));
125 0 : } else if (sps.pic_order_cnt_type == 1) {
126 : // delta_pic_order_always_zero_flag: u(1)
127 0 : RETURN_EMPTY_ON_FAIL(
128 : buffer->ReadBits(&sps.delta_pic_order_always_zero_flag, 1));
129 : // offset_for_non_ref_pic: se(v)
130 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
131 : // offset_for_top_to_bottom_field: se(v)
132 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
133 : // num_ref_frames_in_pic_order_cnt_cycle: ue(v)
134 : uint32_t num_ref_frames_in_pic_order_cnt_cycle;
135 0 : RETURN_EMPTY_ON_FAIL(
136 : buffer->ReadExponentialGolomb(&num_ref_frames_in_pic_order_cnt_cycle));
137 0 : for (size_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) {
138 : // offset_for_ref_frame[i]: se(v)
139 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
140 : }
141 : }
142 : // max_num_ref_frames: ue(v)
143 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.max_num_ref_frames));
144 : // gaps_in_frame_num_value_allowed_flag: u(1)
145 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
146 : //
147 : // IMPORTANT ONES! Now we're getting to resolution. First we read the pic
148 : // width/height in macroblocks (16x16), which gives us the base resolution,
149 : // and then we continue on until we hit the frame crop offsets, which are used
150 : // to signify resolutions that aren't multiples of 16.
151 : //
152 : // pic_width_in_mbs_minus1: ue(v)
153 : uint32_t pic_width_in_mbs_minus1;
154 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&pic_width_in_mbs_minus1));
155 : // pic_height_in_map_units_minus1: ue(v)
156 : uint32_t pic_height_in_map_units_minus1;
157 0 : RETURN_EMPTY_ON_FAIL(
158 : buffer->ReadExponentialGolomb(&pic_height_in_map_units_minus1));
159 : // frame_mbs_only_flag: u(1)
160 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&sps.frame_mbs_only_flag, 1));
161 0 : if (!sps.frame_mbs_only_flag) {
162 : // mb_adaptive_frame_field_flag: u(1)
163 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
164 : }
165 : // direct_8x8_inference_flag: u(1)
166 0 : RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
167 : //
168 : // MORE IMPORTANT ONES! Now we're at the frame crop information.
169 : //
170 : // frame_cropping_flag: u(1)
171 : uint32_t frame_cropping_flag;
172 0 : uint32_t frame_crop_left_offset = 0;
173 0 : uint32_t frame_crop_right_offset = 0;
174 0 : uint32_t frame_crop_top_offset = 0;
175 0 : uint32_t frame_crop_bottom_offset = 0;
176 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&frame_cropping_flag, 1));
177 0 : if (frame_cropping_flag) {
178 : // frame_crop_{left, right, top, bottom}_offset: ue(v)
179 0 : RETURN_EMPTY_ON_FAIL(
180 : buffer->ReadExponentialGolomb(&frame_crop_left_offset));
181 0 : RETURN_EMPTY_ON_FAIL(
182 : buffer->ReadExponentialGolomb(&frame_crop_right_offset));
183 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&frame_crop_top_offset));
184 0 : RETURN_EMPTY_ON_FAIL(
185 : buffer->ReadExponentialGolomb(&frame_crop_bottom_offset));
186 : }
187 : // vui_parameters_present_flag: u(1)
188 0 : RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&sps.vui_params_present, 1));
189 :
190 : // Far enough! We don't use the rest of the SPS.
191 :
192 : // Start with the resolution determined by the pic_width/pic_height fields.
193 0 : sps.width = 16 * (pic_width_in_mbs_minus1 + 1);
194 0 : sps.height =
195 0 : 16 * (2 - sps.frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1);
196 :
197 : // Figure out the crop units in pixels. That's based on the chroma format's
198 : // sampling, which is indicated by chroma_format_idc.
199 0 : if (sps.separate_colour_plane_flag || chroma_format_idc == 0) {
200 0 : frame_crop_bottom_offset *= (2 - sps.frame_mbs_only_flag);
201 0 : frame_crop_top_offset *= (2 - sps.frame_mbs_only_flag);
202 0 : } else if (!sps.separate_colour_plane_flag && chroma_format_idc > 0) {
203 : // Width multipliers for formats 1 (4:2:0) and 2 (4:2:2).
204 0 : if (chroma_format_idc == 1 || chroma_format_idc == 2) {
205 0 : frame_crop_left_offset *= 2;
206 0 : frame_crop_right_offset *= 2;
207 : }
208 : // Height multipliers for format 1 (4:2:0).
209 0 : if (chroma_format_idc == 1) {
210 0 : frame_crop_top_offset *= 2;
211 0 : frame_crop_bottom_offset *= 2;
212 : }
213 : }
214 : // Subtract the crop for each dimension.
215 0 : sps.width -= (frame_crop_left_offset + frame_crop_right_offset);
216 0 : sps.height -= (frame_crop_top_offset + frame_crop_bottom_offset);
217 :
218 0 : return OptionalSps(sps);
219 : }
220 :
221 : } // namespace webrtc
|