[go: nahoru, domu]

vaapi: give up vp8 decoding if the size is changed and the key frame is missing.

WebRTC causes GPU hang on ChromeOS because of this bug.

WebRTC can switch the resolution of video size depending on network condition.
So the first size-changed frame can be inter frame. However, vp8 decoder assumes
the first size-changed frame is always key frame, and passes wrong size value
with the different sized encoded data and then libva causes GPU hang.

Unfortunately, we don't know the first inter frame after rtc dropping frames has
different size or not, because vp8 doesn't store the size in inter frame. So this CL
makes vp8 decoder give up decoding all inter frames when rtc dropping frames.

If vp8 decoder has to skip more than 75 frames (i.e. around 3 secs), it reports
decode error to request new keyframe. In the same sense, vp9 decoder also
doesn't report decode error until 75 frames skipped.

Extract P frame from bear-320x240.webm to add an unittest by Sreerenj
<sreerenj.balachandran@intel.com>
gst-launch-1.0 -v filesrc location=bear-320x240.webm ! matroskademux ! multifilesink location=vp8-frame-320x240_%d

TEST=run https://appr.tc/?vsc=vp8 on 2 IA chromebooks. e.g. KBL, APL, SKL
add VP8DecoderTest in media_unittests
BUG=831037, b/72676160

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I2e116efcc28ebdbea9739c84b28ce3027eac836d
Reviewed-on: https://chromium-review.googlesource.com/1009324
Commit-Queue: Dongseong Hwang <dongseong.hwang@intel.com>
Reviewed-by: Miguel Casas <mcasas@chromium.org>
Reviewed-by: Emircan Uysaler <emircan@chromium.org>
Reviewed-by: Dongseong Hwang <dongseong.hwang@intel.com>
Reviewed-by: Daniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565121}
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index 83a6041..c364812 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -127,9 +127,15 @@
       if (!curr_frame_hdr_->IsKeyframe()) {
         // TODO(posciak): This is doable, but requires a few modifications to
         // VDA implementations to allow multiple picture buffer sets in flight.
+        // http://crbug.com/832264
         DVLOG(1) << "Resolution change currently supported for keyframes only";
-        SetError();
-        return kDecodeError;
+        if (++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) {
+          SetError();
+          return kDecodeError;
+        }
+
+        curr_frame_hdr_.reset();
+        return kRanOutOfStreamData;
       }
 
       // TODO(posciak): This requires us to be on a keyframe (see above) and is
@@ -140,6 +146,7 @@
         ref_frame = nullptr;
 
       pic_size_ = new_pic_size;
+      size_change_failure_counter_ = 0;
       return kAllocateNewSurfaces;
     }