Index: media/video/h264_poc.cc |
diff --git a/media/video/h264_poc.cc b/media/video/h264_poc.cc |
index cfa91057e4490a63399da198204e15bcad6fb731..a171344c756e5010cbedbc9ec9985a6e88ccb145 100644 |
--- a/media/video/h264_poc.cc |
+++ b/media/video/h264_poc.cc |
@@ -13,25 +13,11 @@ |
namespace media { |
-H264POC::H264POC() { |
- Reset(); |
-} |
- |
-H264POC::~H264POC() { |
-} |
- |
-void H264POC::Reset() { |
- // It shouldn't be necessary to reset these values, but doing so will improve |
- // reproducibility for buggy streams. |
- ref_pic_order_cnt_msb_ = 0; |
- ref_pic_order_cnt_lsb_ = 0; |
- prev_frame_num_ = 0; |
- prev_frame_num_offset_ = 0; |
-} |
+namespace { |
// Check if a slice includes memory management control operation 5, which |
// results in some |pic_order_cnt| state being cleared. |
-static bool HasMMCO5(const media::H264SliceHeader& slice_hdr) { |
+bool HasMMCO5(const media::H264SliceHeader& slice_hdr) { |
// Require that the frame actually has memory management control operations. |
if (slice_hdr.nal_ref_idc == 0 || |
slice_hdr.idr_pic_flag || |
@@ -53,6 +39,24 @@ static bool HasMMCO5(const media::H264SliceHeader& slice_hdr) { |
return false; |
} |
+} // namespace |
+ |
+H264POC::H264POC() { |
+ Reset(); |
+} |
+ |
+H264POC::~H264POC() {} |
+ |
+void H264POC::Reset() { |
+ // It shouldn't be necessary to reset these values, but doing so will improve |
+ // reproducibility for buggy streams. |
+ ref_pic_order_cnt_msb_ = 0; |
+ ref_pic_order_cnt_lsb_ = 0; |
+ prev_frame_num_ = 0; |
+ prev_frame_num_offset_ = 0; |
+ pending_mmco5_ = false; |
+} |
+ |
bool H264POC::ComputePicOrderCnt( |
const H264SPS* sps, |
const H264SliceHeader& slice_hdr, |
@@ -67,19 +71,14 @@ bool H264POC::ComputePicOrderCnt( |
int32_t max_pic_order_cnt_lsb = |
1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); |
- // Note: Duplicate frame numbers are ignored. They occur in many videos |
Pawel Osciak
2017/02/17 04:53:26
Should this first note be removed as well?
sandersd (OOO until July 31)
2017/02/18 00:46:34
Yes, it was just plain wrong. (Duplicate frame num
|
- // despite appearing to be invalid according to the spec. |
- // TODO(sandersd): Check if these videos are using slices or have redundant |
- // streams. |
- |
- // Note: Gaps in frame numbers are also ignored. They do not affect POC |
- // computation. |
- |
// Based on T-REC-H.264 8.2.1, "Decoding process for picture order |
// count", available from http://www.itu.int/rec/T-REC-H.264. |
// |
// Reorganized slightly from spec pseudocode to handle MMCO5 when storing |
// state instead of when loading it. |
+ // |
+ // Note: Gaps in frame numbers are ignored. They do not affect POC |
+ // computation. |
switch (sps->pic_order_cnt_type) { |
case 0: { |
int32_t prev_pic_order_cnt_msb = ref_pic_order_cnt_msb_; |
@@ -111,9 +110,15 @@ bool H264POC::ComputePicOrderCnt( |
// (assuming no interlacing). |
int32_t top_foc = pic_order_cnt_msb + slice_hdr.pic_order_cnt_lsb; |
int32_t bottom_foc = top_foc + slice_hdr.delta_pic_order_cnt_bottom; |
- *pic_order_cnt = std::min(top_foc, bottom_foc); |
+ |
+ // Compute POC. |
Pawel Osciak
2017/02/17 04:53:26
Perhaps we could replace this comment with an expl
sandersd (OOO until July 31)
2017/02/22 01:39:32
Done. I went with something similar to what the he
|
+ if (mmco5) |
+ *pic_order_cnt = 0; |
+ else |
+ *pic_order_cnt = std::min(top_foc, bottom_foc); |
// Store state. |
+ pending_mmco5_ = mmco5; |
prev_frame_num_ = slice_hdr.frame_num; |
if (slice_hdr.nal_ref_idc != 0) { |
if (mmco5) { |
@@ -180,13 +185,20 @@ bool H264POC::ComputePicOrderCnt( |
int32_t top_foc = expected_pic_order_cnt + slice_hdr.delta_pic_order_cnt0; |
int32_t bottom_foc = top_foc + sps->offset_for_top_to_bottom_field + |
slice_hdr.delta_pic_order_cnt1; |
- *pic_order_cnt = std::min(top_foc, bottom_foc); |
+ |
+ // Compute POC. |
+ if (mmco5) |
+ *pic_order_cnt = 0; |
+ else |
+ *pic_order_cnt = std::min(top_foc, bottom_foc); |
// Store state. |
+ pending_mmco5_ = mmco5; |
prev_frame_num_ = slice_hdr.frame_num; |
- prev_frame_num_offset_ = frame_num_offset; |
if (mmco5) |
prev_frame_num_offset_ = 0; |
+ else |
+ prev_frame_num_offset_ = frame_num_offset; |
break; |
} |
@@ -203,18 +215,27 @@ bool H264POC::ComputePicOrderCnt( |
// 8-12, 8-13. Derive |temp_pic_order_count| (it's always the |
// |pic_order_cnt|, regardless of interlacing). |
+ int32_t temp_pic_order_count; |
Pawel Osciak
2017/02/17 04:53:26
Perhaps we could say:
if (mmco5)
*pic_order_cnt
sandersd (OOO until July 31)
2017/02/18 00:46:34
I wrote it that way originally, but ended up switc
|
if (slice_hdr.idr_pic_flag) |
- *pic_order_cnt = 0; |
+ temp_pic_order_count = 0; |
else if (slice_hdr.nal_ref_idc == 0) |
- *pic_order_cnt = 2 * (frame_num_offset + slice_hdr.frame_num) - 1; |
+ temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num) - 1; |
+ else |
+ temp_pic_order_count = 2 * (frame_num_offset + slice_hdr.frame_num); |
+ |
+ // Compute POC. |
+ if (mmco5) |
+ *pic_order_cnt = 0; |
else |
- *pic_order_cnt = 2 * (frame_num_offset + slice_hdr.frame_num); |
+ *pic_order_cnt = temp_pic_order_count; |
// Store state. |
+ pending_mmco5_ = mmco5; |
prev_frame_num_ = slice_hdr.frame_num; |
- prev_frame_num_offset_ = frame_num_offset; |
if (mmco5) |
prev_frame_num_offset_ = 0; |
+ else |
+ prev_frame_num_offset_ = frame_num_offset; |
break; |
} |