From 0b53fcfa8ee76ccc2d77abb947810f631efaecd9 Mon Sep 17 00:00:00 2001
From: Thomas Deutschmann <whissi@gentoo.org>
Date: Fri, 11 Dec 2020 15:37:38 +0100
Subject: [PATCH 29/30] bmo#1670333: OpenH264: Fix decoding if it starts on non
 IDR I-frame

Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
---
 dom/media/mp4/MP4Demuxer.cpp       |  8 ++++++++
 dom/media/platforms/PDMFactory.cpp | 15 ++++++++++-----
 dom/media/platforms/PDMFactory.h   |  2 ++
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/dom/media/mp4/MP4Demuxer.cpp b/dom/media/mp4/MP4Demuxer.cpp
index 59bba16577..0304e3e89f 100644
--- a/dom/media/mp4/MP4Demuxer.cpp
+++ b/dom/media/mp4/MP4Demuxer.cpp
@@ -31,6 +31,8 @@ mozilla::LogModule* GetDemuxerLog() { return gMediaDemuxerLog; }
   DDMOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, "::%s: " arg, \
             __func__, ##__VA_ARGS__)
 
+extern bool gUseKeyframeFromContainer;
+
 namespace mozilla {
 
 DDLoggedTypeDeclNameAndBase(MP4TrackDemuxer, MediaTrackDemuxer);
@@ -394,6 +396,12 @@ already_AddRefed<MediaRawData> MP4TrackDemuxer::GetNextSample() {
           [[fallthrough]];
         case H264::FrameType::OTHER: {
           bool keyframe = type == H264::FrameType::I_FRAME;
+          if (gUseKeyframeFromContainer) {
+            if (sample->mKeyframe && sample->mKeyframe != keyframe) {
+              sample->mKeyframe = keyframe;
+            }
+            break;
+          }
           if (sample->mKeyframe != keyframe) {
             NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe "
                                        "@ pts:%" PRId64 " dur:%" PRId64
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index 4e377082ae..e778eb9948 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -58,6 +58,8 @@
 
 #include <functional>
 
+bool gUseKeyframeFromContainer = false;
+
 namespace mozilla {
 
 #define PDM_INIT_LOG(msg, ...) \
@@ -536,10 +538,12 @@ void PDMFactory::CreateContentPDMs() {
   }
 #endif
 #ifdef MOZ_FFMPEG
-  if (StaticPrefs::media_ffmpeg_enabled() &&
-      !CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
-    mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
-        FFmpegRuntimeLinker::LinkStatusCode());
+  if (StaticPrefs::media_ffmpeg_enabled()) {
+    mFFmpegUsed = CreateAndStartupPDM<FFmpegRuntimeLinker>();
+    if (!mFFmpegUsed) {
+      mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
+          FFmpegRuntimeLinker::LinkStatusCode());
+    }
   }
 #endif
 #ifdef MOZ_FFVPX
@@ -556,8 +560,9 @@ void PDMFactory::CreateContentPDMs() {
 
   CreateAndStartupPDM<AgnosticDecoderModule>();
 
-  if (StaticPrefs::media_gmp_decoder_enabled() &&
+  if (StaticPrefs::media_gmp_decoder_enabled() && !mFFmpegUsed &&
       !CreateAndStartupPDM<GMPDecoderModule>()) {
+    gUseKeyframeFromContainer = true;
     mFailureFlags += DecoderDoctorDiagnostics::Flags::GMPPDMFailedToStartup;
   }
 }
diff --git a/dom/media/platforms/PDMFactory.h b/dom/media/platforms/PDMFactory.h
index 4fc81c0b37..72f3255b6f 100644
--- a/dom/media/platforms/PDMFactory.h
+++ b/dom/media/platforms/PDMFactory.h
@@ -122,6 +122,8 @@ class PDMFactory final {
 
   DecoderDoctorDiagnostics::FlagsSet mFailureFlags;
 
+  bool mFFmpegUsed = false;
+
   friend class RemoteVideoDecoderParent;
   static void EnsureInit();
 };
-- 
2.34.1

