OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 #include "webrtc/common_video/h264/h264_bitstream_parser.h" | 10 #include "webrtc/common_video/h264/h264_bitstream_parser.h" |
11 | 11 |
12 #include <memory> | 12 #include <memory> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "webrtc/base/bitbuffer.h" | 15 #include "webrtc/base/bitbuffer.h" |
16 #include "webrtc/base/bytebuffer.h" | 16 #include "webrtc/base/bytebuffer.h" |
17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
18 | 18 |
19 #include "webrtc/common_video/h264/h264_common.h" | 19 #include "webrtc/common_video/h264/h264_common.h" |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
21 | 21 |
22 namespace webrtc { | 22 namespace webrtc { |
23 | 23 |
24 #define RETURN_FALSE_ON_FAIL(x) \ | 24 #define RETURN_ON_FAIL(x, res) \ |
25 if (!(x)) { \ | 25 if (!(x)) { \ |
26 LOG_F(LS_ERROR) << "FAILED: " #x; \ | 26 LOG_F(LS_ERROR) << "FAILED: " #x; \ |
27 return false; \ | 27 return res; \ |
28 } | 28 } |
29 | 29 |
30 #define RETURN_INV_ON_FAIL(x) RETURN_ON_FAIL(x, kInvalidStream) | |
pbos-webrtc
2016/11/03 16:25:25
I think you can s/INV/INVALID_STREAM/g
| |
31 | |
30 H264BitstreamParser::H264BitstreamParser() {} | 32 H264BitstreamParser::H264BitstreamParser() {} |
31 H264BitstreamParser::~H264BitstreamParser() {} | 33 H264BitstreamParser::~H264BitstreamParser() {} |
32 | 34 |
33 bool H264BitstreamParser::ParseNonParameterSetNalu(const uint8_t* source, | 35 H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu( |
34 size_t source_length, | 36 const uint8_t* source, |
35 uint8_t nalu_type) { | 37 size_t source_length, |
36 RTC_CHECK(sps_); | 38 uint8_t nalu_type) { |
37 RTC_CHECK(pps_); | 39 if (!sps_ || !pps_) |
40 return kInvalidStream; | |
41 | |
38 last_slice_qp_delta_ = rtc::Optional<int32_t>(); | 42 last_slice_qp_delta_ = rtc::Optional<int32_t>(); |
39 std::unique_ptr<rtc::Buffer> slice_rbsp( | 43 std::unique_ptr<rtc::Buffer> slice_rbsp( |
40 H264::ParseRbsp(source, source_length)); | 44 H264::ParseRbsp(source, source_length)); |
45 if (slice_rbsp->size() < H264::kNaluTypeSize) | |
46 return kInvalidStream; | |
47 | |
41 rtc::BitBuffer slice_reader(slice_rbsp->data() + H264::kNaluTypeSize, | 48 rtc::BitBuffer slice_reader(slice_rbsp->data() + H264::kNaluTypeSize, |
42 slice_rbsp->size() - H264::kNaluTypeSize); | 49 slice_rbsp->size() - H264::kNaluTypeSize); |
43 // Check to see if this is an IDR slice, which has an extra field to parse | 50 // Check to see if this is an IDR slice, which has an extra field to parse |
44 // out. | 51 // out. |
45 bool is_idr = (source[0] & 0x0F) == H264::NaluType::kIdr; | 52 bool is_idr = (source[0] & 0x0F) == H264::NaluType::kIdr; |
46 uint8_t nal_ref_idc = (source[0] & 0x60) >> 5; | 53 uint8_t nal_ref_idc = (source[0] & 0x60) >> 5; |
47 uint32_t golomb_tmp; | 54 uint32_t golomb_tmp; |
48 uint32_t bits_tmp; | 55 uint32_t bits_tmp; |
49 | 56 |
50 // first_mb_in_slice: ue(v) | 57 // first_mb_in_slice: ue(v) |
51 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 58 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
52 // slice_type: ue(v) | 59 // slice_type: ue(v) |
53 uint32_t slice_type; | 60 uint32_t slice_type; |
54 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&slice_type)); | 61 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&slice_type)); |
55 // slice_type's 5..9 range is used to indicate that all slices of a picture | 62 // slice_type's 5..9 range is used to indicate that all slices of a picture |
56 // have the same value of slice_type % 5, we don't care about that, so we map | 63 // have the same value of slice_type % 5, we don't care about that, so we map |
57 // to the corresponding 0..4 range. | 64 // to the corresponding 0..4 range. |
58 slice_type %= 5; | 65 slice_type %= 5; |
59 // pic_parameter_set_id: ue(v) | 66 // pic_parameter_set_id: ue(v) |
60 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 67 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
61 if (sps_->separate_colour_plane_flag == 1) { | 68 if (sps_->separate_colour_plane_flag == 1) { |
62 // colour_plane_id | 69 // colour_plane_id |
63 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); | 70 RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); |
64 } | 71 } |
65 // frame_num: u(v) | 72 // frame_num: u(v) |
66 // Represented by log2_max_frame_num_minus4 + 4 bits. | 73 // Represented by log2_max_frame_num_minus4 + 4 bits. |
67 RETURN_FALSE_ON_FAIL( | 74 RETURN_INV_ON_FAIL( |
68 slice_reader.ReadBits(&bits_tmp, sps_->log2_max_frame_num_minus4 + 4)); | 75 slice_reader.ReadBits(&bits_tmp, sps_->log2_max_frame_num_minus4 + 4)); |
69 uint32_t field_pic_flag = 0; | 76 uint32_t field_pic_flag = 0; |
70 if (sps_->frame_mbs_only_flag == 0) { | 77 if (sps_->frame_mbs_only_flag == 0) { |
71 // field_pic_flag: u(1) | 78 // field_pic_flag: u(1) |
72 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&field_pic_flag, 1)); | 79 RETURN_INV_ON_FAIL(slice_reader.ReadBits(&field_pic_flag, 1)); |
73 if (field_pic_flag != 0) { | 80 if (field_pic_flag != 0) { |
74 // bottom_field_flag: u(1) | 81 // bottom_field_flag: u(1) |
75 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); | 82 RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); |
76 } | 83 } |
77 } | 84 } |
78 if (is_idr) { | 85 if (is_idr) { |
79 // idr_pic_id: ue(v) | 86 // idr_pic_id: ue(v) |
80 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 87 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
81 } | 88 } |
82 // pic_order_cnt_lsb: u(v) | 89 // pic_order_cnt_lsb: u(v) |
83 // Represented by sps_.log2_max_pic_order_cnt_lsb_minus4 + 4 bits. | 90 // Represented by sps_.log2_max_pic_order_cnt_lsb_minus4 + 4 bits. |
84 if (sps_->pic_order_cnt_type == 0) { | 91 if (sps_->pic_order_cnt_type == 0) { |
85 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits( | 92 RETURN_INV_ON_FAIL(slice_reader.ReadBits( |
86 &bits_tmp, sps_->log2_max_pic_order_cnt_lsb_minus4 + 4)); | 93 &bits_tmp, sps_->log2_max_pic_order_cnt_lsb_minus4 + 4)); |
87 if (pps_->bottom_field_pic_order_in_frame_present_flag && | 94 if (pps_->bottom_field_pic_order_in_frame_present_flag && |
88 field_pic_flag == 0) { | 95 field_pic_flag == 0) { |
89 // delta_pic_order_cnt_bottom: se(v) | 96 // delta_pic_order_cnt_bottom: se(v) |
90 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 97 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
91 } | 98 } |
92 } | 99 } |
93 if (sps_->pic_order_cnt_type == 1 && | 100 if (sps_->pic_order_cnt_type == 1 && |
94 !sps_->delta_pic_order_always_zero_flag) { | 101 !sps_->delta_pic_order_always_zero_flag) { |
95 // delta_pic_order_cnt[0]: se(v) | 102 // delta_pic_order_cnt[0]: se(v) |
96 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 103 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
97 if (pps_->bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) { | 104 if (pps_->bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) { |
98 // delta_pic_order_cnt[1]: se(v) | 105 // delta_pic_order_cnt[1]: se(v) |
99 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 106 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
100 } | 107 } |
101 } | 108 } |
102 if (pps_->redundant_pic_cnt_present_flag) { | 109 if (pps_->redundant_pic_cnt_present_flag) { |
103 // redundant_pic_cnt: ue(v) | 110 // redundant_pic_cnt: ue(v) |
104 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 111 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
105 } | 112 } |
106 if (slice_type == H264::SliceType::kB) { | 113 if (slice_type == H264::SliceType::kB) { |
107 // direct_spatial_mv_pred_flag: u(1) | 114 // direct_spatial_mv_pred_flag: u(1) |
108 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); | 115 RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); |
109 } | 116 } |
110 switch (slice_type) { | 117 switch (slice_type) { |
111 case H264::SliceType::kP: | 118 case H264::SliceType::kP: |
112 case H264::SliceType::kB: | 119 case H264::SliceType::kB: |
113 case H264::SliceType::kSp: | 120 case H264::SliceType::kSp: |
114 uint32_t num_ref_idx_active_override_flag; | 121 uint32_t num_ref_idx_active_override_flag; |
115 // num_ref_idx_active_override_flag: u(1) | 122 // num_ref_idx_active_override_flag: u(1) |
116 RETURN_FALSE_ON_FAIL( | 123 RETURN_INV_ON_FAIL( |
117 slice_reader.ReadBits(&num_ref_idx_active_override_flag, 1)); | 124 slice_reader.ReadBits(&num_ref_idx_active_override_flag, 1)); |
118 if (num_ref_idx_active_override_flag != 0) { | 125 if (num_ref_idx_active_override_flag != 0) { |
119 // num_ref_idx_l0_active_minus1: ue(v) | 126 // num_ref_idx_l0_active_minus1: ue(v) |
120 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 127 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
121 if (slice_type == H264::SliceType::kB) { | 128 if (slice_type == H264::SliceType::kB) { |
122 // num_ref_idx_l1_active_minus1: ue(v) | 129 // num_ref_idx_l1_active_minus1: ue(v) |
123 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 130 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
124 } | 131 } |
125 } | 132 } |
126 break; | 133 break; |
127 default: | 134 default: |
128 break; | 135 break; |
129 } | 136 } |
130 // assume nal_unit_type != 20 && nal_unit_type != 21: | 137 // assume nal_unit_type != 20 && nal_unit_type != 21: |
131 RTC_CHECK_NE(nalu_type, 20); | 138 if (nalu_type == 20 || nalu_type == 21) { |
132 RTC_CHECK_NE(nalu_type, 21); | 139 LOG(LS_ERROR) << "Unsupported nal unit type."; |
140 return kUnsupportedStream; | |
141 } | |
133 // if (nal_unit_type == 20 || nal_unit_type == 21) | 142 // if (nal_unit_type == 20 || nal_unit_type == 21) |
134 // ref_pic_list_mvc_modification() | 143 // ref_pic_list_mvc_modification() |
135 // else | 144 // else |
136 { | 145 { |
137 // ref_pic_list_modification(): | 146 // ref_pic_list_modification(): |
138 // |slice_type| checks here don't use named constants as they aren't named | 147 // |slice_type| checks here don't use named constants as they aren't named |
139 // in the spec for this segment. Keeping them consistent makes it easier to | 148 // in the spec for this segment. Keeping them consistent makes it easier to |
140 // verify that they are both the same. | 149 // verify that they are both the same. |
141 if (slice_type % 5 != 2 && slice_type % 5 != 4) { | 150 if (slice_type % 5 != 2 && slice_type % 5 != 4) { |
142 // ref_pic_list_modification_flag_l0: u(1) | 151 // ref_pic_list_modification_flag_l0: u(1) |
143 uint32_t ref_pic_list_modification_flag_l0; | 152 uint32_t ref_pic_list_modification_flag_l0; |
144 RETURN_FALSE_ON_FAIL( | 153 RETURN_INV_ON_FAIL( |
145 slice_reader.ReadBits(&ref_pic_list_modification_flag_l0, 1)); | 154 slice_reader.ReadBits(&ref_pic_list_modification_flag_l0, 1)); |
146 if (ref_pic_list_modification_flag_l0) { | 155 if (ref_pic_list_modification_flag_l0) { |
147 uint32_t modification_of_pic_nums_idc; | 156 uint32_t modification_of_pic_nums_idc; |
148 do { | 157 do { |
149 // modification_of_pic_nums_idc: ue(v) | 158 // modification_of_pic_nums_idc: ue(v) |
150 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb( | 159 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb( |
151 &modification_of_pic_nums_idc)); | 160 &modification_of_pic_nums_idc)); |
152 if (modification_of_pic_nums_idc == 0 || | 161 if (modification_of_pic_nums_idc == 0 || |
153 modification_of_pic_nums_idc == 1) { | 162 modification_of_pic_nums_idc == 1) { |
154 // abs_diff_pic_num_minus1: ue(v) | 163 // abs_diff_pic_num_minus1: ue(v) |
155 RETURN_FALSE_ON_FAIL( | 164 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
156 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
157 } else if (modification_of_pic_nums_idc == 2) { | 165 } else if (modification_of_pic_nums_idc == 2) { |
158 // long_term_pic_num: ue(v) | 166 // long_term_pic_num: ue(v) |
159 RETURN_FALSE_ON_FAIL( | 167 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
160 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
161 } | 168 } |
162 } while (modification_of_pic_nums_idc != 3); | 169 } while (modification_of_pic_nums_idc != 3); |
163 } | 170 } |
164 } | 171 } |
165 if (slice_type % 5 == 1) { | 172 if (slice_type % 5 == 1) { |
166 // ref_pic_list_modification_flag_l1: u(1) | 173 // ref_pic_list_modification_flag_l1: u(1) |
167 uint32_t ref_pic_list_modification_flag_l1; | 174 uint32_t ref_pic_list_modification_flag_l1; |
168 RETURN_FALSE_ON_FAIL( | 175 RETURN_INV_ON_FAIL( |
169 slice_reader.ReadBits(&ref_pic_list_modification_flag_l1, 1)); | 176 slice_reader.ReadBits(&ref_pic_list_modification_flag_l1, 1)); |
170 if (ref_pic_list_modification_flag_l1) { | 177 if (ref_pic_list_modification_flag_l1) { |
171 uint32_t modification_of_pic_nums_idc; | 178 uint32_t modification_of_pic_nums_idc; |
172 do { | 179 do { |
173 // modification_of_pic_nums_idc: ue(v) | 180 // modification_of_pic_nums_idc: ue(v) |
174 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb( | 181 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb( |
175 &modification_of_pic_nums_idc)); | 182 &modification_of_pic_nums_idc)); |
176 if (modification_of_pic_nums_idc == 0 || | 183 if (modification_of_pic_nums_idc == 0 || |
177 modification_of_pic_nums_idc == 1) { | 184 modification_of_pic_nums_idc == 1) { |
178 // abs_diff_pic_num_minus1: ue(v) | 185 // abs_diff_pic_num_minus1: ue(v) |
179 RETURN_FALSE_ON_FAIL( | 186 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
180 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
181 } else if (modification_of_pic_nums_idc == 2) { | 187 } else if (modification_of_pic_nums_idc == 2) { |
182 // long_term_pic_num: ue(v) | 188 // long_term_pic_num: ue(v) |
183 RETURN_FALSE_ON_FAIL( | 189 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
184 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
185 } | 190 } |
186 } while (modification_of_pic_nums_idc != 3); | 191 } while (modification_of_pic_nums_idc != 3); |
187 } | 192 } |
188 } | 193 } |
189 } | 194 } |
190 // TODO(pbos): Do we need support for pred_weight_table()? | 195 // TODO(pbos): Do we need support for pred_weight_table()? |
191 RTC_CHECK( | 196 if ((pps_->weighted_pred_flag && (slice_type == H264::SliceType::kP || |
192 !((pps_->weighted_pred_flag && (slice_type == H264::SliceType::kP || | 197 slice_type == H264::SliceType::kSp)) || |
193 slice_type == H264::SliceType::kSp)) || | 198 (pps_->weighted_bipred_idc == 1 && slice_type == H264::SliceType::kB)) { |
194 (pps_->weighted_bipred_idc != 0 && slice_type == H264::SliceType::kB))) | 199 LOG(LS_ERROR) << "Streams with pred_weight_table unsupported."; |
195 << "Missing support for pred_weight_table()."; | 200 return kUnsupportedStream; |
201 } | |
196 // if ((weighted_pred_flag && (slice_type == P || slice_type == SP)) || | 202 // if ((weighted_pred_flag && (slice_type == P || slice_type == SP)) || |
197 // (weighted_bipred_idc == 1 && slice_type == B)) { | 203 // (weighted_bipred_idc == 1 && slice_type == B)) { |
198 // pred_weight_table() | 204 // pred_weight_table() |
199 // } | 205 // } |
200 if (nal_ref_idc != 0) { | 206 if (nal_ref_idc != 0) { |
201 // dec_ref_pic_marking(): | 207 // dec_ref_pic_marking(): |
202 if (is_idr) { | 208 if (is_idr) { |
203 // no_output_of_prior_pics_flag: u(1) | 209 // no_output_of_prior_pics_flag: u(1) |
204 // long_term_reference_flag: u(1) | 210 // long_term_reference_flag: u(1) |
205 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); | 211 RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); |
206 } else { | 212 } else { |
207 // adaptive_ref_pic_marking_mode_flag: u(1) | 213 // adaptive_ref_pic_marking_mode_flag: u(1) |
208 uint32_t adaptive_ref_pic_marking_mode_flag; | 214 uint32_t adaptive_ref_pic_marking_mode_flag; |
209 RETURN_FALSE_ON_FAIL( | 215 RETURN_INV_ON_FAIL( |
210 slice_reader.ReadBits(&adaptive_ref_pic_marking_mode_flag, 1)); | 216 slice_reader.ReadBits(&adaptive_ref_pic_marking_mode_flag, 1)); |
211 if (adaptive_ref_pic_marking_mode_flag) { | 217 if (adaptive_ref_pic_marking_mode_flag) { |
212 uint32_t memory_management_control_operation; | 218 uint32_t memory_management_control_operation; |
213 do { | 219 do { |
214 // memory_management_control_operation: ue(v) | 220 // memory_management_control_operation: ue(v) |
215 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb( | 221 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb( |
216 &memory_management_control_operation)); | 222 &memory_management_control_operation)); |
217 if (memory_management_control_operation == 1 || | 223 if (memory_management_control_operation == 1 || |
218 memory_management_control_operation == 3) { | 224 memory_management_control_operation == 3) { |
219 // difference_of_pic_nums_minus1: ue(v) | 225 // difference_of_pic_nums_minus1: ue(v) |
220 RETURN_FALSE_ON_FAIL( | 226 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
221 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
222 } | 227 } |
223 if (memory_management_control_operation == 2) { | 228 if (memory_management_control_operation == 2) { |
224 // long_term_pic_num: ue(v) | 229 // long_term_pic_num: ue(v) |
225 RETURN_FALSE_ON_FAIL( | 230 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
226 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
227 } | 231 } |
228 if (memory_management_control_operation == 3 || | 232 if (memory_management_control_operation == 3 || |
229 memory_management_control_operation == 6) { | 233 memory_management_control_operation == 6) { |
230 // long_term_frame_idx: ue(v) | 234 // long_term_frame_idx: ue(v) |
231 RETURN_FALSE_ON_FAIL( | 235 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
232 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
233 } | 236 } |
234 if (memory_management_control_operation == 4) { | 237 if (memory_management_control_operation == 4) { |
235 // max_long_term_frame_idx_plus1: ue(v) | 238 // max_long_term_frame_idx_plus1: ue(v) |
236 RETURN_FALSE_ON_FAIL( | 239 RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
237 slice_reader.ReadExponentialGolomb(&golomb_tmp)); | |
238 } | 240 } |
239 } while (memory_management_control_operation != 0); | 241 } while (memory_management_control_operation != 0); |
240 } | 242 } |
241 } | 243 } |
242 } | 244 } |
243 // cabac not supported: entropy_coding_mode_flag == 0 asserted above. | 245 // cabac not supported: entropy_coding_mode_flag == 0 asserted above. |
244 // if (entropy_coding_mode_flag && slice_type != I && slice_type != SI) | 246 // if (entropy_coding_mode_flag && slice_type != I && slice_type != SI) |
245 // cabac_init_idc | 247 // cabac_init_idc |
246 int32_t last_slice_qp_delta; | 248 int32_t last_slice_qp_delta; |
247 RETURN_FALSE_ON_FAIL( | 249 RETURN_INV_ON_FAIL( |
248 slice_reader.ReadSignedExponentialGolomb(&last_slice_qp_delta)); | 250 slice_reader.ReadSignedExponentialGolomb(&last_slice_qp_delta)); |
249 last_slice_qp_delta_ = rtc::Optional<int32_t>(last_slice_qp_delta); | 251 last_slice_qp_delta_ = rtc::Optional<int32_t>(last_slice_qp_delta); |
250 return true; | 252 return kOk; |
251 } | 253 } |
252 | 254 |
253 void H264BitstreamParser::ParseSlice(const uint8_t* slice, size_t length) { | 255 void H264BitstreamParser::ParseSlice(const uint8_t* slice, size_t length) { |
254 H264::NaluType nalu_type = H264::ParseNaluType(slice[0]); | 256 H264::NaluType nalu_type = H264::ParseNaluType(slice[0]); |
255 switch (nalu_type) { | 257 switch (nalu_type) { |
256 case H264::NaluType::kSps: { | 258 case H264::NaluType::kSps: { |
257 sps_ = SpsParser::ParseSps(slice + H264::kNaluTypeSize, | 259 sps_ = SpsParser::ParseSps(slice + H264::kNaluTypeSize, |
258 length - H264::kNaluTypeSize); | 260 length - H264::kNaluTypeSize); |
259 if (!sps_) | 261 if (!sps_) |
260 FATAL() << "Unable to parse SPS from H264 bitstream."; | 262 LOG(LS_WARNING) << "Unable to parse SPS from H264 bitstream."; |
261 break; | 263 break; |
262 } | 264 } |
263 case H264::NaluType::kPps: { | 265 case H264::NaluType::kPps: { |
264 pps_ = PpsParser::ParsePps(slice + H264::kNaluTypeSize, | 266 pps_ = PpsParser::ParsePps(slice + H264::kNaluTypeSize, |
265 length - H264::kNaluTypeSize); | 267 length - H264::kNaluTypeSize); |
266 if (!pps_) | 268 if (!pps_) |
267 FATAL() << "Unable to parse PPS from H264 bitstream."; | 269 LOG(LS_WARNING) << "Unable to parse PPS from H264 bitstream."; |
268 break; | 270 break; |
269 } | 271 } |
270 default: | 272 default: |
271 RTC_CHECK(ParseNonParameterSetNalu(slice, length, nalu_type)) | 273 Result res = ParseNonParameterSetNalu(slice, length, nalu_type); |
272 << "Failed to parse picture slice."; | 274 if (res != kOk) |
275 LOG(LS_INFO) << "Failed to parse bitstream. Error: " << res; | |
magjed_webrtc
2016/11/03 21:27:48
nit: I think we should do at least LS_WARNING here
| |
273 break; | 276 break; |
274 } | 277 } |
275 } | 278 } |
276 | 279 |
277 void H264BitstreamParser::ParseBitstream(const uint8_t* bitstream, | 280 void H264BitstreamParser::ParseBitstream(const uint8_t* bitstream, |
278 size_t length) { | 281 size_t length) { |
279 std::vector<H264::NaluIndex> nalu_indices = | 282 std::vector<H264::NaluIndex> nalu_indices = |
280 H264::FindNaluIndices(bitstream, length); | 283 H264::FindNaluIndices(bitstream, length); |
281 RTC_CHECK(!nalu_indices.empty()); | |
282 for (const H264::NaluIndex& index : nalu_indices) | 284 for (const H264::NaluIndex& index : nalu_indices) |
283 ParseSlice(&bitstream[index.payload_start_offset], index.payload_size); | 285 ParseSlice(&bitstream[index.payload_start_offset], index.payload_size); |
284 } | 286 } |
285 | 287 |
286 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { | 288 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { |
287 if (!last_slice_qp_delta_ || !pps_) | 289 if (!last_slice_qp_delta_ || !pps_) |
288 return false; | 290 return false; |
289 *qp = 26 + pps_->pic_init_qp_minus26 + *last_slice_qp_delta_; | 291 *qp = 26 + pps_->pic_init_qp_minus26 + *last_slice_qp_delta_; |
290 return true; | 292 return true; |
291 } | 293 } |
292 | 294 |
293 } // namespace webrtc | 295 } // namespace webrtc |
OLD | NEW |