- Revision
- 259363
- Author
- jer.no...@apple.com
- Date
- 2020-04-01 14:15:18 -0700 (Wed, 01 Apr 2020)
Log Message
CRASH in MediaPlayerPrivateMediaSourceAVFObjC::addAudioRenderer(), uncaught ObjC exception
https://bugs.webkit.org/show_bug.cgi?id=209827
<rdar://problem/61113080>
Reviewed by Eric Carlson.
-[AVSampleBufferAudioRenderer init] can, in exceptional conditions, return nil. Passing a
nil object, or another object that AVSampleBufferRenderSynchronizer considers "invalid", into
-[AVSampleBufferRenderSynchronizer addRenderer:] will throw an exception. Protect against this
scenario in two ways:
- Check the return value of -[AVSampleBufferAudioRenderer init], and if nil, log an error,
log to console, and set the network state to "DecodeError".
- Wrap calls to -addRenderer: in @try/@catch blocks, which if caught, log an error, assert,
and set the network state to "DecodeError".
* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::failedToCreateRenderer):
* Modules/mediasource/MediaSource.h:
* platform/graphics/MediaSourcePrivateClient.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::ensureLayer):
* platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm:
(WebCore::MediaSourcePrivateAVFObjC::failedToCreateAudioRenderer):
(WebCore::MediaSourcePrivateAVFObjC::failedToCreateVideoRenderer):
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
(WebCore::SourceBufferPrivateAVFObjC::trackDidChangeEnabled):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (259362 => 259363)
--- trunk/Source/WebCore/ChangeLog 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/ChangeLog 2020-04-01 21:15:18 UTC (rev 259363)
@@ -1,3 +1,34 @@
+2020-04-01 Jer Noble <jer.no...@apple.com>
+
+ CRASH in MediaPlayerPrivateMediaSourceAVFObjC::addAudioRenderer(), uncaught ObjC exception
+ https://bugs.webkit.org/show_bug.cgi?id=209827
+ <rdar://problem/61113080>
+
+ Reviewed by Eric Carlson.
+
+ -[AVSampleBufferAudioRenderer init] can, in exceptional conditions, return nil. Passing a
+ nil object, or another object that AVSampleBufferRenderSynchronizer considers "invalid", into
+ -[AVSampleBufferRenderSynchronizer addRenderer:] will throw an exception. Protect against this
+ scenario in two ways:
+
+ - Check the return value of -[AVSampleBufferAudioRenderer init], and if nil, log an error,
+ log to console, and set the network state to "DecodeError".
+ - Wrap calls to -addRenderer: in @try/@catch blocks, which if caught, log an error, assert,
+ and set the network state to "DecodeError".
+
+ * Modules/mediasource/MediaSource.cpp:
+ (WebCore::MediaSource::failedToCreateRenderer):
+ * Modules/mediasource/MediaSource.h:
+ * platform/graphics/MediaSourcePrivateClient.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::ensureLayer):
+ * platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm:
+ (WebCore::MediaSourcePrivateAVFObjC::failedToCreateAudioRenderer):
+ (WebCore::MediaSourcePrivateAVFObjC::failedToCreateVideoRenderer):
+ * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+ (WebCore::SourceBufferPrivateAVFObjC::trackDidChangeEnabled):
+
2020-04-01 Chris Dumez <cdu...@apple.com>
ASSERTION FAILED: m_wrapper on imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp (259362 => 259363)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2020-04-01 21:15:18 UTC (rev 259363)
@@ -1093,6 +1093,12 @@
}
#endif
+void MediaSource::failedToCreateRenderer(RendererType type)
+{
+ if (auto context = scriptExecutionContext())
+ context->addConsoleMessage(MessageSource::JS, MessageLevel::Error, makeString("MediaSource ", type == RendererType::Video ? "video" : "audio", " renderer creation failed."));
}
+}
+
#endif
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (259362 => 259363)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2020-04-01 21:15:18 UTC (rev 259363)
@@ -122,6 +122,8 @@
void setLogIdentifier(const void*) final;
#endif
+ void failedToCreateRenderer(RendererType) final;
+
private:
explicit MediaSource(ScriptExecutionContext&);
Modified: trunk/Source/WebCore/platform/graphics/MediaSourcePrivateClient.h (259362 => 259363)
--- trunk/Source/WebCore/platform/graphics/MediaSourcePrivateClient.h 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/platform/graphics/MediaSourcePrivateClient.h 2020-04-01 21:15:18 UTC (rev 259363)
@@ -50,6 +50,9 @@
#if !RELEASE_LOG_DISABLED
virtual void setLogIdentifier(const void*) = 0;
#endif
+
+ enum class RendererType { Audio, Video };
+ virtual void failedToCreateRenderer(RendererType) = 0;
};
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (259362 => 259363)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2020-04-01 21:15:18 UTC (rev 259363)
@@ -766,6 +766,14 @@
[m_sampleBufferDisplayLayer setName:@"MediaPlayerPrivateMediaSource AVSampleBufferDisplayLayer"];
#endif
+ if (!m_sampleBufferDisplayLayer) {
+ ERROR_LOG(LOGIDENTIFIER, "Failed to create AVSampleBufferDisplayLayer");
+ if (m_mediaSourcePrivate)
+ m_mediaSourcePrivate->failedToCreateRenderer(MediaSourcePrivateAVFObjC::RendererType::Video);
+ setNetworkState(MediaPlayer::NetworkState::DecodeError);
+ return;
+ }
+
#if HAVE(AVSAMPLEBUFFERVIDEOOUTPUT)
ASSERT(!m_videoOutput);
if (isVideoOutputAvailable()) {
@@ -775,17 +783,19 @@
}
#endif
- ASSERT(m_sampleBufferDisplayLayer);
- if (!m_sampleBufferDisplayLayer) {
- ERROR_LOG(LOGIDENTIFIER, "Failed to create AVSampleBufferDisplayLayer");
+ if ([m_sampleBufferDisplayLayer respondsToSelector:@selector(setPreventsDisplaySleepDuringVideoPlayback:)])
+ m_sampleBufferDisplayLayer.get().preventsDisplaySleepDuringVideoPlayback = NO;
+
+ @try {
+ [m_synchronizer addRenderer:m_sampleBufferDisplayLayer.get()];
+ } @catch(NSException *exception) {
+ ERROR_LOG(LOGIDENTIFIER, "-[AVSampleBufferRenderSynchronizer addRenderer:] threw an exception: ", [[exception name] UTF8String], ", reason : ", [[exception reason] UTF8String]);
+ ASSERT_NOT_REACHED();
+
setNetworkState(MediaPlayer::NetworkState::DecodeError);
return;
}
- if ([m_sampleBufferDisplayLayer respondsToSelector:@selector(setPreventsDisplaySleepDuringVideoPlayback:)])
- m_sampleBufferDisplayLayer.get().preventsDisplaySleepDuringVideoPlayback = NO;
-
- [m_synchronizer addRenderer:m_sampleBufferDisplayLayer.get()];
if (m_mediaSourcePrivate)
m_mediaSourcePrivate->setVideoLayer(m_sampleBufferDisplayLayer.get());
m_videoLayerManager->setVideoLayer(m_sampleBufferDisplayLayer.get(), snappedIntRect(m_player->playerContentBoxRect()).size());
@@ -1153,6 +1163,11 @@
void MediaPlayerPrivateMediaSourceAVFObjC::addAudioRenderer(AVSampleBufferAudioRenderer* audioRenderer)
ALLOW_NEW_API_WITHOUT_GUARDS_END
{
+ if (!audioRenderer) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
if (!m_sampleBufferAudioRendererMap.add((__bridge CFTypeRef)audioRenderer, AudioRendererProperties()).isNewEntry)
return;
@@ -1160,7 +1175,15 @@
[audioRenderer setVolume:m_player->volume()];
[audioRenderer setAudioTimePitchAlgorithm:(m_player->preservesPitch() ? AVAudioTimePitchAlgorithmSpectral : AVAudioTimePitchAlgorithmVarispeed)];
- [m_synchronizer addRenderer:audioRenderer];
+ @try {
+ [m_synchronizer addRenderer:audioRenderer];
+ } @catch(NSException *exception) {
+ ERROR_LOG(LOGIDENTIFIER, "-[AVSampleBufferRenderSynchronizer addRenderer:] threw an exception: ", [[exception name] UTF8String], ", reason : ", [[exception reason] UTF8String]);
+ ASSERT_NOT_REACHED();
+
+ setNetworkState(MediaPlayer::NetworkState::DecodeError);
+ return;
+ }
m_player->renderingModeChanged();
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h (259362 => 259363)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h 2020-04-01 21:15:18 UTC (rev 259363)
@@ -29,6 +29,7 @@
#if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
#include "MediaSourcePrivate.h"
+#include "MediaSourcePrivateClient.h"
#include <wtf/Deque.h>
#include <wtf/LoggerHelper.h>
#include <wtf/RefPtr.h>
@@ -110,6 +111,9 @@
const void* nextSourceBufferLogIdentifier() { return childLogIdentifier(m_logIdentifier, ++m_nextSourceBufferID); }
#endif
+ using RendererType = MediaSourcePrivateClient::RendererType;
+ void failedToCreateRenderer(RendererType);
+
private:
MediaSourcePrivateAVFObjC(MediaPlayerPrivateMediaSourceAVFObjC*, MediaSourcePrivateClient*);
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm (259362 => 259363)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm 2020-04-01 21:15:18 UTC (rev 259363)
@@ -325,6 +325,11 @@
}
#endif
+void MediaSourcePrivateAVFObjC::failedToCreateRenderer(RendererType type)
+{
+ m_client->failedToCreateRenderer(type);
}
+}
+
#endif // ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm (259362 => 259363)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm 2020-04-01 21:01:40 UTC (rev 259362)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm 2020-04-01 21:15:18 UTC (rev 259363)
@@ -897,6 +897,15 @@
ALLOW_NEW_API_WITHOUT_GUARDS_END
if (!m_audioRenderers.contains(trackID)) {
renderer = adoptNS([PAL::allocAVSampleBufferAudioRendererInstance() init]);
+
+ if (!renderer) {
+ ERROR_LOG(LOGIDENTIFIER, "-[AVSampleBufferAudioRenderer init] returned nil! bailing!");
+ if (m_mediaSource)
+ m_mediaSource->failedToCreateRenderer(MediaSourcePrivateAVFObjC::RendererType::Audio);
+ m_mediaSource->player()->setNetworkState(MediaPlayer::NetworkState::DecodeError);
+ return;
+ }
+
auto weakThis = makeWeakPtr(*this);
[renderer requestMediaDataWhenReadyOnQueue:dispatch_get_main_queue() usingBlock:^{
if (weakThis)