| 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 |