Chromium Code Reviews| Index: media/gpu/video_encode_accelerator_unittest.cc |
| diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc |
| index 4e0dd6ad8ec14bcdf064266d6eb131e9d8a9b3d5..88a722a2e689b7f9153c6153864ddb68ca00f584 100644 |
| --- a/media/gpu/video_encode_accelerator_unittest.cc |
| +++ b/media/gpu/video_encode_accelerator_unittest.cc |
| @@ -604,12 +604,18 @@ class H264Validator : public StreamValidator { |
| void ProcessStreamBuffer(const uint8_t* stream, size_t size) override; |
| private: |
| + bool IsNewFrame(const H264NALU& nalu, int sps_id); |
| + bool IsNewPrimaryCodedPicture(const H264SliceHeader* slice_hdr, |
| + int sps_id) const; |
| + |
| // Set to true when encoder provides us with the corresponding NALU type. |
| bool seen_sps_; |
| bool seen_pps_; |
| bool seen_idr_; |
| H264Parser h264_parser_; |
| + std::unique_ptr<H264SliceHeader> curr_slice_hdr_; |
| + int curr_pic_order_cnt_type_; |
| }; |
| void H264Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { |
| @@ -624,9 +630,9 @@ void H264Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { |
| break; |
| ASSERT_EQ(H264Parser::kOk, result); |
| - |
| bool keyframe = false; |
| + int sps_id = 0; |
| switch (nalu.nal_unit_type) { |
| case H264NALU::kIDRSlice: |
| ASSERT_TRUE(seen_sps_); |
| @@ -636,14 +642,12 @@ void H264Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { |
| // fallthrough |
| case H264NALU::kNonIDRSlice: { |
| ASSERT_TRUE(seen_idr_); |
| - seen_sps_ = seen_pps_ = false; |
| - if (!frame_cb_.Run(keyframe)) |
| + if (IsNewFrame(nalu, sps_id) && !frame_cb_.Run(keyframe)) |
| return; |
| break; |
| } |
| case H264NALU::kSPS: { |
| - int sps_id; |
| ASSERT_EQ(H264Parser::kOk, h264_parser_.ParseSPS(&sps_id)); |
| seen_sps_ = true; |
| break; |
| @@ -663,6 +667,67 @@ void H264Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { |
| } |
| } |
| +bool H264Validator::IsNewFrame(const H264NALU& nalu, int sps_id) { |
| + std::unique_ptr<H264SliceHeader> slice_hdr(new H264SliceHeader()); |
| + const bool par_res = h264_parser_.ParseSliceHeader(nalu, slice_hdr.get()); |
| + if (par_res != H264Parser::kOk) { |
| + LOG(ERROR) << "Cannot parse H264 slice header."; |
| + return true; |
| + } |
| + |
| + const bool is_new_frame = IsNewPrimaryCodedPicture(slice_hdr.get(), sps_id); |
| + |
| + curr_slice_hdr_.reset(slice_hdr.release()); |
| + if (seen_sps_) { |
| + const H264SPS* sps = h264_parser_.GetSPS(sps_id); |
| + if (!sps) { |
| + LOG(ERROR) << "Cannot parse SPS."; |
| + return true; |
| + } |
| + curr_pic_order_cnt_type_ = sps->pic_order_cnt_type; |
| + } |
| + return is_new_frame; |
| +} |
| + |
| +// This function follows the checks from H264Decoder::IsNewPrimaryCodedPicture() |
| +// to identify if the given |slice_hdr| belongs to a new frame. |
| +bool H264Validator::IsNewPrimaryCodedPicture(const H264SliceHeader* slice_hdr, |
|
Pawel Osciak
2016/11/30 02:05:22
Perhaps we would be able to turn H264Decoder::IsNe
emircan
2016/12/05 21:24:31
Done.
|
| + int sps_id) const { |
| + if (!curr_slice_hdr_) |
| + return true; |
| + |
| + if (slice_hdr->frame_num != curr_slice_hdr_->frame_num || |
| + slice_hdr->pic_parameter_set_id != |
| + curr_slice_hdr_->pic_parameter_set_id || |
| + slice_hdr->nal_ref_idc != curr_slice_hdr_->nal_ref_idc || |
| + slice_hdr->idr_pic_flag != curr_slice_hdr_->idr_pic_flag || |
| + (slice_hdr->idr_pic_flag && |
| + (slice_hdr->idr_pic_id != curr_slice_hdr_->idr_pic_id || |
| + slice_hdr->first_mb_in_slice == 0))) |
| + return true; |
| + |
| + const H264SPS* sps = h264_parser_.GetSPS(sps_id); |
| + if (!sps) |
| + return false; |
| + |
| + if (sps->pic_order_cnt_type == curr_pic_order_cnt_type_) { |
| + if (curr_pic_order_cnt_type_ == 0) { |
| + if (slice_hdr->pic_order_cnt_lsb != curr_slice_hdr_->pic_order_cnt_lsb || |
| + slice_hdr->delta_pic_order_cnt_bottom != |
| + curr_slice_hdr_->delta_pic_order_cnt_bottom) |
| + return true; |
| + } else if (curr_pic_order_cnt_type_ == 1) { |
| + if (slice_hdr->delta_pic_order_cnt0 != |
| + curr_slice_hdr_->delta_pic_order_cnt0 || |
| + slice_hdr->delta_pic_order_cnt1 != |
| + curr_slice_hdr_->delta_pic_order_cnt1) |
| + return true; |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| class VP8Validator : public StreamValidator { |
| public: |
| explicit VP8Validator(const FrameFoundCallback& frame_cb) |
| @@ -2101,6 +2166,13 @@ INSTANTIATE_TEST_CASE_P(MultipleEncoders, |
| false, |
| false, |
| false))); |
| + |
| +INSTANTIATE_TEST_CASE_P( |
| + VerifyTimestamp, |
| + VideoEncodeAcceleratorTest, |
| + ::testing::Values( |
| + std::make_tuple(1, false, 0, false, false, false, false, false, true))); |
| + |
| #if defined(OS_WIN) |
| INSTANTIATE_TEST_CASE_P( |
| ForceBitrate, |