Title: [291290] trunk/Source/WebCore
Revision
291290
Author
eoca...@igalia.com
Date
2022-03-15 08:23:14 -0700 (Tue, 15 Mar 2022)

Log Message

[GStreamer] clarify playback errors with MediaError.message
https://bugs.webkit.org/show_bug.cgi?id=237602

Reviewed by Philippe Normand.

This patch is co-authored by Eugene Mutavchi <ievgen_mutav...@comcast.com>
See: https://github.com/WebPlatformForEmbedded/WPEWebKit/pull/797

* html/HTMLMediaElement.cpp: Use internal last error message from the player, if available.
* platform/graphics/MediaPlayer.cpp: Cache the last error message from the player private and update it when NetworkState changes to an error state. This allows the player private to be regenerated (as it has always been) while providing access to the former player private error after that.
* platform/graphics/MediaPlayer.h: Added lastErrorMessage() method to get the last internal error message from the player private.
* platform/graphics/MediaPlayerPrivate.h: Default lastErrorMessage() empty implementation.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: Detect decryption and no-key errors.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Added errorMessage() to expose the internal error message.
* platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: Post multiple kind of errors to the GstBus to notify upper layers instead of just logging them.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (291289 => 291290)


--- trunk/Source/WebCore/ChangeLog	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/ChangeLog	2022-03-15 15:23:14 UTC (rev 291290)
@@ -1,3 +1,21 @@
+2022-03-15  Enrique Ocaña González  <eoca...@igalia.com>
+
+        [GStreamer] clarify playback errors with MediaError.message
+        https://bugs.webkit.org/show_bug.cgi?id=237602
+
+        Reviewed by Philippe Normand.
+
+        This patch is co-authored by Eugene Mutavchi <ievgen_mutav...@comcast.com>
+        See: https://github.com/WebPlatformForEmbedded/WPEWebKit/pull/797
+
+        * html/HTMLMediaElement.cpp: Use internal last error message from the player, if available.
+        * platform/graphics/MediaPlayer.cpp: Cache the last error message from the player private and update it when NetworkState changes to an error state. This allows the player private to be regenerated (as it has always been) while providing access to the former player private error after that.
+        * platform/graphics/MediaPlayer.h: Added lastErrorMessage() method to get the last internal error message from the player private.
+        * platform/graphics/MediaPlayerPrivate.h: Default lastErrorMessage() empty implementation.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: Detect decryption and no-key errors.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Added errorMessage() to expose the internal error message.
+        * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: Post multiple kind of errors to the GstBus to notify upper layers instead of just logging them.
+
 2022-03-15  Antti Koivisto  <an...@apple.com>
 
         CSSConditionRule.conditionText should be readonly

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (291289 => 291290)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2022-03-15 15:23:14 UTC (rev 291290)
@@ -2175,7 +2175,9 @@
 
     // 6.1 - Set the error attribute to a new MediaError object whose code attribute is set to
     // MEDIA_ERR_SRC_NOT_SUPPORTED.
-    m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED, "Unsupported source type"_s);
+    m_error = m_player
+        ? MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED, m_player->lastErrorMessage())
+        : MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED, "Unsupported source type"_s);
 
     // 6.2 - Forget the media element's media-resource-specific text tracks.
     forgetResourceSpecificTracks();
@@ -2213,12 +2215,24 @@
     stopPeriodicTimers();
     m_loadState = WaitingForSource;
 
+    const auto getErrorMessage = [&] (String&& defaultMessage) {
+        String message = WTFMove(defaultMessage);
+        if (!m_player)
+            return message;
+
+        auto lastErrorMessage = m_player->lastErrorMessage();
+        if (!lastErrorMessage)
+            return message;
+
+        return makeString(message, ": ", lastErrorMessage);
+    };
+
     // 2 - Set the error attribute to a new MediaError object whose code attribute is
     // set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE.
     if (error == MediaPlayer::NetworkState::NetworkError)
-        m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK, "Media failed to load"_s);
+        m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK, getErrorMessage("Media failed to load"_s));
     else if (error == MediaPlayer::NetworkState::DecodeError)
-        m_error = MediaError::create(MediaError::MEDIA_ERR_DECODE, "Media failed to decode"_s);
+        m_error = MediaError::create(MediaError::MEDIA_ERR_DECODE, getErrorMessage("Media failed to decode"_s));
     else
         ASSERT_NOT_REACHED();
 

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2022-03-15 15:23:14 UTC (rev 291290)
@@ -1333,6 +1333,7 @@
     // If more than one media engine is installed and this one failed before finding metadata,
     // let the next engine try.
     if (m_private->networkState() >= MediaPlayer::NetworkState::FormatError && m_private->readyState() < MediaPlayer::ReadyState::HaveMetadata) {
+        m_lastErrorMessage = m_private->errorMessage();
         client().mediaPlayerEngineFailedToLoad();
         if (!m_activeEngineIdentifier && installedMediaEngines().size() > 1 && (m_contentType.isEmpty() || nextBestMediaEngine(m_currentMediaEngine))) {
             m_reloadTimer.startOneShot(0_s);
@@ -1912,6 +1913,11 @@
     return values[static_cast<size_t>(enumerationValue)];
 }
 
+String MediaPlayer::lastErrorMessage() const
+{
+    return m_lastErrorMessage;
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2022-03-15 15:23:14 UTC (rev 291290)
@@ -697,6 +697,8 @@
 
     void playerContentBoxRectChanged(const LayoutRect&);
 
+    String lastErrorMessage() const;
+
 private:
     MediaPlayer(MediaPlayerClient&);
     MediaPlayer(MediaPlayerClient&, MediaPlayerEnums::MediaEngineIdentifier);
@@ -741,6 +743,7 @@
     bool m_shouldContinueAfterKeyNeeded { false };
 #endif
     bool m_isGatheringVideoFrameMetadata { false };
+    String m_lastErrorMessage;
 };
 
 class MediaPlayerFactory {

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2022-03-15 15:23:14 UTC (rev 291290)
@@ -329,6 +329,8 @@
     virtual void playerContentBoxRectChanged(const LayoutRect&) { }
 
     virtual void setResourceOwner(const ProcessIdentity&) { }
+
+    virtual String errorMessage() const { return { }; }
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2022-03-15 15:23:14 UTC (rev 291290)
@@ -1728,8 +1728,12 @@
         gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
         GST_ERROR("Error %d: %s (url="" err->code, err->message, m_url.string().utf8().data());
 
+        m_errorMessage = err->message;
+
         error = MediaPlayer::NetworkState::Empty;
         if (g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_CODEC_NOT_FOUND)
+            || g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_DECRYPT)
+            || g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_DECRYPT_NOKEY)
             || g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE)
             || g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED)
             || g_error_matches(err.get(), GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN)

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2022-03-15 15:23:14 UTC (rev 291290)
@@ -392,6 +392,8 @@
 
     std::optional<GstVideoDecoderPlatform> m_videoDecoderPlatform;
 
+    String errorMessage() const override { return m_errorMessage; }
+
 private:
     class TaskAtMediaTimeScheduler {
     public:
@@ -579,6 +581,7 @@
 #endif
 
     RefPtr<GBMBufferSwapchain> m_swapchain;
+    String m_errorMessage;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp (291289 => 291290)


--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp	2022-03-15 15:02:03 UTC (rev 291289)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp	2022-03-15 15:23:14 UTC (rev 291290)
@@ -210,7 +210,7 @@
             return GST_FLOW_FLUSHING;
         }
         if (!priv->cdmProxy) {
-            GST_ERROR_OBJECT(self, "CDMProxy was not retrieved in time");
+            GST_ELEMENT_ERROR(self, STREAM, FAILED, ("CDMProxy was not retrieved in time"), (nullptr));
             return GST_FLOW_NOT_SUPPORTED;
         }
         GST_DEBUG_OBJECT(self, "CDM now available with address %p", priv->cdmProxy.get());
@@ -224,11 +224,11 @@
 
     unsigned ivSize;
     if (!gst_structure_get_uint(protectionMeta->info, "iv_size", &ivSize)) {
-        GST_ERROR_OBJECT(self, "Failed to get iv_size");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get iv_size"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
     if (!ivSize && !gst_structure_get_uint(protectionMeta->info, "constant_iv_size", &ivSize)) {
-        GST_ERROR_OBJECT(self, "No iv_size and failed to get constant_iv_size");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("No iv_size and failed to get constant_iv_size"), (nullptr));
         ASSERT(isCbcs);
         return GST_FLOW_NOT_SUPPORTED;
     }
@@ -235,7 +235,7 @@
 
     gboolean encrypted;
     if (!gst_structure_get_boolean(protectionMeta->info, "encrypted", &encrypted)) {
-        GST_ERROR_OBJECT(self, "Failed to get encrypted flag");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get encrypted flag"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
 
@@ -249,7 +249,7 @@
     unsigned subSampleCount = 0;
     // cbcs could not include the subsample_count.
     if (!gst_structure_get_uint(protectionMeta->info, "subsample_count", &subSampleCount) && !isCbcs) {
-        GST_ERROR_OBJECT(self, "Failed to get subsample_count");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get subsample_count"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
 
@@ -258,12 +258,12 @@
     if (subSampleCount) {
         value = gst_structure_get_value(protectionMeta->info, "subsamples");
         if (!value) {
-            GST_ERROR_OBJECT(self, "Failed to get subsamples");
+            GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get subsamples"), (nullptr));
             return GST_FLOW_NOT_SUPPORTED;
         }
         subSamplesBuffer = gst_value_get_buffer(value);
         if (!subSamplesBuffer) {
-            GST_ERROR_OBJECT(self, "There is no subsamples buffer, but a positive subsample count");
+            GST_ELEMENT_ERROR(self, STREAM, FAILED, ("There is no subsamples buffer, but a positive subsample count"), (nullptr));
             return GST_FLOW_NOT_SUPPORTED;
         }
     }
@@ -271,7 +271,7 @@
     value = gst_structure_get_value(protectionMeta->info, "kid");
 
     if (!value) {
-        GST_ERROR_OBJECT(self, "Failed to get key id for buffer");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get key id for buffer"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
     GstBuffer* keyIDBuffer = gst_value_get_buffer(value);
@@ -278,7 +278,7 @@
 
     value = gst_structure_get_value(protectionMeta->info, "iv");
     if (!value) {
-        GST_ERROR_OBJECT(self, "Failed to get IV for sample");
+        GST_ELEMENT_ERROR(self, STREAM, FAILED, ("Failed to get IV for sample"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
 
@@ -307,7 +307,7 @@
             GST_DEBUG_OBJECT(self, "Decryption aborted because of flush");
             return GST_FLOW_FLUSHING;
         }
-        GST_ERROR_OBJECT(self, "Decryption failed");
+        GST_ELEMENT_ERROR(self, STREAM, DECRYPT, ("Decryption failed"), (nullptr));
         return GST_FLOW_NOT_SUPPORTED;
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to