OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 void H264POC::Reset() { | 50 void H264POC::Reset() { |
51 // It shouldn't be necessary to reset these values, but doing so will improve | 51 // It shouldn't be necessary to reset these values, but doing so will improve |
52 // reproducibility for buggy streams. | 52 // reproducibility for buggy streams. |
53 ref_pic_order_cnt_msb_ = 0; | 53 ref_pic_order_cnt_msb_ = 0; |
54 ref_pic_order_cnt_lsb_ = 0; | 54 ref_pic_order_cnt_lsb_ = 0; |
55 prev_frame_num_ = 0; | 55 prev_frame_num_ = 0; |
56 prev_frame_num_offset_ = 0; | 56 prev_frame_num_offset_ = 0; |
57 pending_mmco5_ = false; | 57 pending_mmco5_ = false; |
58 } | 58 } |
59 | 59 |
60 bool H264POC::ComputePicOrderCnt( | 60 base::Optional<int32_t> H264POC::ComputePicOrderCnt( |
61 const H264SPS* sps, | 61 const H264SPS* sps, |
62 const H264SliceHeader& slice_hdr, | 62 const H264SliceHeader& slice_hdr) { |
63 int32_t *pic_order_cnt) { | |
64 if (slice_hdr.field_pic_flag) { | 63 if (slice_hdr.field_pic_flag) { |
65 DLOG(ERROR) << "Interlaced frames are not supported"; | 64 DLOG(ERROR) << "Interlaced frames are not supported"; |
66 return false; | 65 return base::nullopt; |
67 } | 66 } |
68 | 67 |
| 68 int32_t pic_order_cnt = 0; |
69 bool mmco5 = HasMMCO5(slice_hdr); | 69 bool mmco5 = HasMMCO5(slice_hdr); |
70 int32_t max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); | 70 int32_t max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); |
71 int32_t max_pic_order_cnt_lsb = | 71 int32_t max_pic_order_cnt_lsb = |
72 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); | 72 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); |
73 | 73 |
74 // Based on T-REC-H.264 8.2.1, "Decoding process for picture order | 74 // Based on T-REC-H.264 8.2.1, "Decoding process for picture order |
75 // count", available from http://www.itu.int/rec/T-REC-H.264. | 75 // count", available from http://www.itu.int/rec/T-REC-H.264. |
76 // | 76 // |
77 // Reorganized slightly from spec pseudocode to handle MMCO5 when storing | 77 // Reorganized slightly from spec pseudocode to handle MMCO5 when storing |
78 // state instead of when loading it. | 78 // state instead of when loading it. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // (assuming no interlacing). | 110 // (assuming no interlacing). |
111 int32_t top_foc = pic_order_cnt_msb + slice_hdr.pic_order_cnt_lsb; | 111 int32_t top_foc = pic_order_cnt_msb + slice_hdr.pic_order_cnt_lsb; |
112 int32_t bottom_foc = top_foc + slice_hdr.delta_pic_order_cnt_bottom; | 112 int32_t bottom_foc = top_foc + slice_hdr.delta_pic_order_cnt_bottom; |
113 | 113 |
114 // Compute POC. | 114 // Compute POC. |
115 // | 115 // |
116 // MMCO5, like IDR, starts a new reordering group. The POC is specified to | 116 // MMCO5, like IDR, starts a new reordering group. The POC is specified to |
117 // change to 0 after decoding; we change it immediately and set the | 117 // change to 0 after decoding; we change it immediately and set the |
118 // |pending_mmco5_| flag. | 118 // |pending_mmco5_| flag. |
119 if (mmco5) | 119 if (mmco5) |
120 *pic_order_cnt = 0; | 120 pic_order_cnt = 0; |
121 else | 121 else |
122 *pic_order_cnt = std::min(top_foc, bottom_foc); | 122 pic_order_cnt = std::min(top_foc, bottom_foc); |
123 | 123 |
124 // Store state. | 124 // Store state. |
125 pending_mmco5_ = mmco5; | 125 pending_mmco5_ = mmco5; |
126 prev_frame_num_ = slice_hdr.frame_num; | 126 prev_frame_num_ = slice_hdr.frame_num; |
127 if (slice_hdr.nal_ref_idc != 0) { | 127 if (slice_hdr.nal_ref_idc != 0) { |
128 if (mmco5) { | 128 if (mmco5) { |
129 ref_pic_order_cnt_msb_ = 0; | 129 ref_pic_order_cnt_msb_ = 0; |
130 ref_pic_order_cnt_lsb_ = top_foc; | 130 ref_pic_order_cnt_lsb_ = top_foc; |
131 } else { | 131 } else { |
132 ref_pic_order_cnt_msb_ = pic_order_cnt_msb; | 132 ref_pic_order_cnt_msb_ = pic_order_cnt_msb; |
(...skipping 26 matching lines...) Expand all Loading... |
159 | 159 |
160 // 8-9. Derive |expected_pic_order_cnt| (the |pic_order_cnt| indicated | 160 // 8-9. Derive |expected_pic_order_cnt| (the |pic_order_cnt| indicated |
161 // by the cycle described in the SPS). | 161 // by the cycle described in the SPS). |
162 int32_t expected_pic_order_cnt = 0; | 162 int32_t expected_pic_order_cnt = 0; |
163 if (abs_frame_num > 0) { | 163 if (abs_frame_num > 0) { |
164 // 8-8. Derive pic_order_cnt_cycle_cnt and | 164 // 8-8. Derive pic_order_cnt_cycle_cnt and |
165 // frame_num_in_pic_order_cnt_cycle. | 165 // frame_num_in_pic_order_cnt_cycle. |
166 // Moved inside 8-9 to avoid division when this check is not done. | 166 // Moved inside 8-9 to avoid division when this check is not done. |
167 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) { | 167 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) { |
168 DLOG(ERROR) << "Invalid num_ref_frames_in_pic_order_cnt_cycle"; | 168 DLOG(ERROR) << "Invalid num_ref_frames_in_pic_order_cnt_cycle"; |
169 return false; | 169 return base::nullopt; |
170 } | 170 } |
171 | 171 |
172 // H264Parser checks that num_ref_frames_in_pic_order_cnt_cycle < 255. | 172 // H264Parser checks that num_ref_frames_in_pic_order_cnt_cycle < 255. |
173 int32_t pic_order_cnt_cycle_cnt = | 173 int32_t pic_order_cnt_cycle_cnt = |
174 (abs_frame_num - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle; | 174 (abs_frame_num - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle; |
175 int32_t frame_num_in_pic_order_cnt_cycle = | 175 int32_t frame_num_in_pic_order_cnt_cycle = |
176 (abs_frame_num - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle; | 176 (abs_frame_num - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle; |
177 | 177 |
178 // 8-9 continued. | 178 // 8-9 continued. |
179 expected_pic_order_cnt = pic_order_cnt_cycle_cnt * | 179 expected_pic_order_cnt = pic_order_cnt_cycle_cnt * |
180 sps->expected_delta_per_pic_order_cnt_cycle; | 180 sps->expected_delta_per_pic_order_cnt_cycle; |
181 for (int32_t i = 0; i <= frame_num_in_pic_order_cnt_cycle; i++) | 181 for (int32_t i = 0; i <= frame_num_in_pic_order_cnt_cycle; i++) |
182 expected_pic_order_cnt += sps->offset_for_ref_frame[i]; | 182 expected_pic_order_cnt += sps->offset_for_ref_frame[i]; |
183 } | 183 } |
184 if (slice_hdr.nal_ref_idc == 0) | 184 if (slice_hdr.nal_ref_idc == 0) |
185 expected_pic_order_cnt += sps->offset_for_non_ref_pic; | 185 expected_pic_order_cnt += sps->offset_for_non_ref_pic; |
186 | 186 |
187 // 8-10. Derive |top_field_order_cnt| and |bottom_field_order_cnt| | 187 // 8-10. Derive |top_field_order_cnt| and |bottom_field_order_cnt| |
188 // (assuming no interlacing). | 188 // (assuming no interlacing). |
189 int32_t top_foc = expected_pic_order_cnt + slice_hdr.delta_pic_order_cnt0; | 189 int32_t top_foc = expected_pic_order_cnt + slice_hdr.delta_pic_order_cnt0; |
190 int32_t bottom_foc = top_foc + sps->offset_for_top_to_bottom_field + | 190 int32_t bottom_foc = top_foc + sps->offset_for_top_to_bottom_field + |
191 slice_hdr.delta_pic_order_cnt1; | 191 slice_hdr.delta_pic_order_cnt1; |
192 | 192 |
193 // Compute POC. MMCO5 handling is the same as |pic_order_cnt_type| == 0. | 193 // Compute POC. MMCO5 handling is the same as |pic_order_cnt_type| == 0. |
194 if (mmco5) | 194 if (mmco5) |
195 *pic_order_cnt = 0; | 195 pic_order_cnt = 0; |
196 else | 196 else |
197 *pic_order_cnt = std::min(top_foc, bottom_foc); | 197 pic_order_cnt = std::min(top_foc, bottom_foc); |
198 | 198 |
199 // Store state. | 199 // Store state. |
200 pending_mmco5_ = mmco5; | 200 pending_mmco5_ = mmco5; |
201 prev_frame_num_ = slice_hdr.frame_num; | 201 prev_frame_num_ = slice_hdr.frame_num; |
202 if (mmco5) | 202 if (mmco5) |
203 prev_frame_num_offset_ = 0; | 203 prev_frame_num_offset_ = 0; |
204 else | 204 else |
205 prev_frame_num_offset_ = frame_num_offset; | 205 prev_frame_num_offset_ = frame_num_offset; |
206 | 206 |
207 break; | 207 break; |
(...skipping 14 matching lines...) Expand all Loading... |
222 int32_t temp_pic_order_count; | 222 int32_t temp_pic_order_count; |
223 if (slice_hdr.idr_pic_flag) | 223 if (slice_hdr.idr_pic_flag) |
224 temp_pic_order_count = 0; | 224 temp_pic_order_count = 0; |
225 else if (slice_hdr.nal_ref_idc == 0) | 225 else if (slice_hdr.nal_ref_idc == 0) |
226 temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num) - 1; | 226 temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num) - 1; |
227 else | 227 else |
228 temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num); | 228 temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num); |
229 | 229 |
230 // Compute POC. MMCO5 handling is the same as |pic_order_cnt_type| == 0. | 230 // Compute POC. MMCO5 handling is the same as |pic_order_cnt_type| == 0. |
231 if (mmco5) | 231 if (mmco5) |
232 *pic_order_cnt = 0; | 232 pic_order_cnt = 0; |
233 else | 233 else |
234 *pic_order_cnt = temp_pic_order_count; | 234 pic_order_cnt = temp_pic_order_count; |
235 | 235 |
236 // Store state. | 236 // Store state. |
237 pending_mmco5_ = mmco5; | 237 pending_mmco5_ = mmco5; |
238 prev_frame_num_ = slice_hdr.frame_num; | 238 prev_frame_num_ = slice_hdr.frame_num; |
239 if (mmco5) | 239 if (mmco5) |
240 prev_frame_num_offset_ = 0; | 240 prev_frame_num_offset_ = 0; |
241 else | 241 else |
242 prev_frame_num_offset_ = frame_num_offset; | 242 prev_frame_num_offset_ = frame_num_offset; |
243 | 243 |
244 break; | 244 break; |
245 } | 245 } |
246 | 246 |
247 default: | 247 default: |
248 DLOG(ERROR) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type; | 248 DLOG(ERROR) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type; |
249 return false; | 249 return base::nullopt; |
250 } | 250 } |
251 | 251 |
252 return true; | 252 return pic_order_cnt; |
253 } | 253 } |
254 | 254 |
255 } // namespace media | 255 } // namespace media |
OLD | NEW |