Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1274)

Unified Diff: media/gpu/h264_decoder.cc

Issue 2538883002: Detect H264 slices of the same frame in VEAUnittest (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/gpu/h264_decoder.h ('k') | media/gpu/video_encode_accelerator_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/h264_decoder.cc
diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc
index e81121737ac6461f46f2434713135499954c63ce..7f4b7e2916a1d5b448f3b7b5b07b8e5b3cc0f8ad 100644
--- a/media/gpu/h264_decoder.cc
+++ b/media/gpu/h264_decoder.cc
@@ -110,55 +110,11 @@ bool H264Decoder::InitNonexistingPicture(scoped_refptr<H264Picture> pic,
}
bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) {
- DCHECK(curr_pic_.get());
-
- curr_pic_->idr = slice_hdr->idr_pic_flag;
- if (curr_pic_->idr)
- curr_pic_->idr_pic_id = slice_hdr->idr_pic_id;
-
- if (slice_hdr->field_pic_flag) {
- curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM
- : H264Picture::FIELD_TOP;
- } else {
- curr_pic_->field = H264Picture::FIELD_NONE;
- }
-
- if (curr_pic_->field != H264Picture::FIELD_NONE) {
- DVLOG(1) << "Interlaced video not supported.";
- return false;
- }
-
- curr_pic_->nal_ref_idc = slice_hdr->nal_ref_idc;
- curr_pic_->ref = slice_hdr->nal_ref_idc != 0;
- // This assumes non-interlaced stream.
- curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num;
-
- DCHECK_NE(curr_sps_id_, -1);
- const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
- if (!sps)
+ curr_pic_ = CreateH264PictureFromSliceHeader(parser_.GetSPS(curr_sps_id_),
+ *slice_hdr);
+ if (!curr_pic_)
return false;
- curr_pic_->pic_order_cnt_type = sps->pic_order_cnt_type;
- switch (curr_pic_->pic_order_cnt_type) {
- case 0:
- curr_pic_->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb;
- curr_pic_->delta_pic_order_cnt_bottom =
- slice_hdr->delta_pic_order_cnt_bottom;
- break;
-
- case 1:
- curr_pic_->delta_pic_order_cnt0 = slice_hdr->delta_pic_order_cnt0;
- curr_pic_->delta_pic_order_cnt1 = slice_hdr->delta_pic_order_cnt1;
- break;
-
- case 2:
- break;
-
- default:
- NOTREACHED();
- return false;
- }
-
if (!CalculatePicOrderCounts(curr_pic_))
return false;
@@ -1180,53 +1136,12 @@ bool H264Decoder::HandleFrameNumGap(int frame_num) {
return true;
}
-bool H264Decoder::IsNewPrimaryCodedPicture(
- const H264SliceHeader* slice_hdr) const {
- if (!curr_pic_)
- return true;
-
- // 7.4.1.2.4, assumes non-interlaced.
- if (slice_hdr->frame_num != curr_pic_->frame_num ||
- slice_hdr->pic_parameter_set_id != curr_pps_id_ ||
- slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc ||
- slice_hdr->idr_pic_flag != curr_pic_->idr ||
- (slice_hdr->idr_pic_flag &&
- (slice_hdr->idr_pic_id != curr_pic_->idr_pic_id ||
- // If we have two consecutive IDR slices, and the second one has
- // first_mb_in_slice == 0, treat it as a new picture.
- // Per spec, idr_pic_id should not be equal in this case (and we should
- // have hit the condition above instead, see spec 7.4.3 on idr_pic_id),
- // but some encoders neglect changing idr_pic_id for two consecutive
- // IDRs. Work around this by checking if the next slice contains the
- // zeroth macroblock, i.e. data that belongs to the next picture.
- slice_hdr->first_mb_in_slice == 0)))
- return true;
-
- const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
- if (!sps)
- return false;
-
- if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) {
- if (curr_pic_->pic_order_cnt_type == 0) {
- if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb ||
- slice_hdr->delta_pic_order_cnt_bottom !=
- curr_pic_->delta_pic_order_cnt_bottom)
- return true;
- } else if (curr_pic_->pic_order_cnt_type == 1) {
- if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 ||
- slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1)
- return true;
- }
- }
-
- return false;
-}
-
bool H264Decoder::PreprocessCurrentSlice() {
const H264SliceHeader* slice_hdr = curr_slice_hdr_.get();
DCHECK(slice_hdr);
- if (IsNewPrimaryCodedPicture(slice_hdr)) {
+ if (IsNewPrimaryCodedPicture(curr_pic_, curr_pps_id_,
+ parser_.GetSPS(curr_sps_id_), *slice_hdr)) {
// New picture, so first finish the previous one before processing it.
if (!FinishPrevFrameIfPresent())
return false;
@@ -1439,4 +1354,99 @@ size_t H264Decoder::GetRequiredNumOfPictures() const {
return dpb_.max_num_pics() + kPicsInPipeline;
}
+// static
+scoped_refptr<H264Picture> H264Decoder::CreateH264PictureFromSliceHeader(
+ const H264SPS* sps,
+ const H264SliceHeader& slice_hdr) {
+ scoped_refptr<H264Picture> pic(new H264Picture());
+ pic->idr = slice_hdr.idr_pic_flag;
+ if (pic->idr)
+ pic->idr_pic_id = slice_hdr.idr_pic_id;
+
+ if (slice_hdr.field_pic_flag) {
+ pic->field = slice_hdr.bottom_field_flag ? H264Picture::FIELD_BOTTOM
+ : H264Picture::FIELD_TOP;
+ } else {
+ pic->field = H264Picture::FIELD_NONE;
+ }
+
+ if (pic->field != H264Picture::FIELD_NONE) {
+ DVLOG(1) << "Interlaced video not supported.";
+ return nullptr;
+ }
+
+ pic->nal_ref_idc = slice_hdr.nal_ref_idc;
+ pic->ref = slice_hdr.nal_ref_idc != 0;
+ // This assumes non-interlaced stream.
+ pic->frame_num = pic->pic_num = slice_hdr.frame_num;
+
+ if (!sps)
+ return nullptr;
+
+ pic->pic_order_cnt_type = sps->pic_order_cnt_type;
+ switch (pic->pic_order_cnt_type) {
+ case 0:
+ pic->pic_order_cnt_lsb = slice_hdr.pic_order_cnt_lsb;
+ pic->delta_pic_order_cnt_bottom = slice_hdr.delta_pic_order_cnt_bottom;
+ break;
+
+ case 1:
+ pic->delta_pic_order_cnt0 = slice_hdr.delta_pic_order_cnt0;
+ pic->delta_pic_order_cnt1 = slice_hdr.delta_pic_order_cnt1;
+ break;
+
+ case 2:
+ break;
+
+ default:
+ NOTREACHED();
+ return nullptr;
+ }
+ return pic;
+}
+
+// static
+bool H264Decoder::IsNewPrimaryCodedPicture(scoped_refptr<H264Picture> curr_pic,
+ int curr_pps_id,
+ const H264SPS* sps,
+ const H264SliceHeader& slice_hdr) {
+ if (!curr_pic)
+ return true;
+
+ // 7.4.1.2.4, assumes non-interlaced.
+ if (slice_hdr.frame_num != curr_pic->frame_num ||
+ slice_hdr.pic_parameter_set_id != curr_pps_id ||
+ slice_hdr.nal_ref_idc != curr_pic->nal_ref_idc ||
+ slice_hdr.idr_pic_flag != curr_pic->idr ||
+ (slice_hdr.idr_pic_flag &&
+ (slice_hdr.idr_pic_id != curr_pic->idr_pic_id ||
+ // If we have two consecutive IDR slices, and the second one has
+ // first_mb_in_slice == 0, treat it as a new picture.
+ // Per spec, idr_pic_id should not be equal in this case (and we should
+ // have hit the condition above instead, see spec 7.4.3 on idr_pic_id),
+ // but some encoders neglect changing idr_pic_id for two consecutive
+ // IDRs. Work around this by checking if the next slice contains the
+ // zeroth macroblock, i.e. data that belongs to the next picture.
+ slice_hdr.first_mb_in_slice == 0)))
+ return true;
+
+ if (!sps)
+ return false;
+
+ if (sps->pic_order_cnt_type == curr_pic->pic_order_cnt_type) {
+ if (curr_pic->pic_order_cnt_type == 0) {
+ if (slice_hdr.pic_order_cnt_lsb != curr_pic->pic_order_cnt_lsb ||
+ slice_hdr.delta_pic_order_cnt_bottom !=
+ curr_pic->delta_pic_order_cnt_bottom)
+ return true;
+ } else if (curr_pic->pic_order_cnt_type == 1) {
+ if (slice_hdr.delta_pic_order_cnt0 != curr_pic->delta_pic_order_cnt0 ||
+ slice_hdr.delta_pic_order_cnt1 != curr_pic->delta_pic_order_cnt1)
+ return true;
+ }
+ }
+
+ return false;
+}
+
} // namespace media
« no previous file with comments | « media/gpu/h264_decoder.h ('k') | media/gpu/video_encode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698