Diff
Modified: trunk/Source/WebCore/ChangeLog (291032 => 291033)
--- trunk/Source/WebCore/ChangeLog 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/ChangeLog 2022-03-09 07:38:58 UTC (rev 291033)
@@ -1,3 +1,37 @@
+2022-03-08 Jean-Yves Avenard <j...@apple.com>
+
+ Have MediaFormatReader plugin use WebMParser directly
+ https://bugs.webkit.org/show_bug.cgi?id=237594
+ rdar://89960307
+
+ Reviewed by Eric Carlson.
+
+ Covered by existing tests.
+
+ * platform/MediaSample.h:
+ (WebCore::MediaSample::byteRange const): Have default implementation.
+ * platform/VideoFrame.cpp:
+ * platform/VideoFrame.h:
+ * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
+ (WebCore::ImageDecoderAVFObjCSample::byteRangeForAttachment const):
+ * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
+ * platform/graphics/cocoa/CMUtilities.h: Export symbols.
+ * platform/graphics/cocoa/SourceBufferParserWebM.cpp:
+ (WebCore::WebMParser::createByteRangeSamples):
+ (WebCore::WebMParser::OnTrackEntry):
+ (WebCore::WebMParser::VideoTrackData::consumeFrameData):
+ (WebCore::WebMParser::AudioTrackData::consumeFrameData):
+ (WebCore::WebMParser::provideMediaData):
+ (WebCore::SourceBufferParserWebM::parsedMediaData):
+ (WebCore::SourceBufferParserWebM::returnSamples):
+ (WebCore::SourceBufferParserWebM::flushPendingAudioSamples):
+ * platform/graphics/cocoa/SourceBufferParserWebM.h:
+ (WebCore::WebMParser::TrackData::createByteRangeSamples):
+ (WebCore::WebMParser::TrackData::drainPendingSamples):
+ * platform/graphics/gstreamer/MediaSampleGStreamer.h:
+ * platform/mock/mediasource/MockSourceBufferPrivate.cpp:
+
2022-03-08 Chris Dumez <cdu...@apple.com>
IntersectionObserver is causing massive document leaks on haaretz.co.il
Modified: trunk/Source/WebCore/platform/MediaSample.h (291032 => 291033)
--- trunk/Source/WebCore/platform/MediaSample.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/MediaSample.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -30,6 +30,7 @@
#include "PlatformVideoColorSpace.h"
#include "SharedBuffer.h"
#include <_javascript_Core/TypedArrays.h>
+#include <functional>
#include <wtf/EnumTraits.h>
#include <wtf/MediaTime.h>
#include <wtf/ThreadSafeRefCounted.h>
@@ -47,6 +48,7 @@
class MockSampleBox;
class ProcessIdentity;
class SharedBuffer;
+struct TrackInfo;
struct PlatformSample {
enum Type {
@@ -61,7 +63,7 @@
const MockSampleBox* mockSampleBox;
CMSampleBufferRef cmSampleBuffer;
GstSample* gstSample;
- std::pair<MTPluginByteSourceRef, CMFormatDescriptionRef> byteRangeSample;
+ std::pair<MTPluginByteSourceRef, std::reference_wrapper<const TrackInfo>> byteRangeSample;
} sample;
};
@@ -107,7 +109,7 @@
size_t byteOffset { 0 };
size_t byteLength { 0 };
};
- virtual std::optional<ByteRange> byteRange() const = 0;
+ virtual std::optional<ByteRange> byteRange() const { return std::nullopt; }
enum class VideoRotation {
None = 0,
@@ -227,11 +229,13 @@
class MediaSamplesBlock {
public:
+ using MediaSampleDataType = std::variant<MediaSample::ByteRange, Ref<const FragmentedSharedBuffer>>;
struct MediaSampleItem {
+ using MediaSampleDataType = MediaSamplesBlock::MediaSampleDataType;
MediaTime presentationTime;
MediaTime decodeTime;
MediaTime duration;
- std::variant<MediaSample::ByteRange, Ref<const FragmentedSharedBuffer>> data;
+ MediaSampleDataType data;
MediaSample::SampleFlags flags;
};
Modified: trunk/Source/WebCore/platform/VideoFrame.cpp (291032 => 291033)
--- trunk/Source/WebCore/platform/VideoFrame.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/VideoFrame.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -108,13 +108,6 @@
return MediaSample::SampleFlags::None;
}
-std::optional<MediaSample::ByteRange> VideoFrame::byteRange() const
-{
- // FIXME: Remove from the base class.
- ASSERT_NOT_REACHED();
- return std::nullopt;
-}
-
void VideoFrame::dump(PrintStream&) const
{
}
Modified: trunk/Source/WebCore/platform/VideoFrame.h (291032 => 291033)
--- trunk/Source/WebCore/platform/VideoFrame.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/VideoFrame.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -74,7 +74,6 @@
WEBCORE_EXPORT void setTimestamps(const MediaTime&, const MediaTime&) final;
WEBCORE_EXPORT Ref<WebCore::MediaSample> createNonDisplayingCopy() const final;
WEBCORE_EXPORT SampleFlags flags() const final;
- WEBCORE_EXPORT std::optional<ByteRange> byteRange() const final;
WEBCORE_EXPORT void dump(PrintStream&) const final;
};
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm 2022-03-09 07:38:58 UTC (rev 291033)
@@ -53,6 +53,7 @@
#import <wtf/MediaTime.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/Vector.h>
+#import <wtf/cf/TypeCastsCF.h>
#import "CoreVideoSoftLink.h"
#import "VideoToolboxSoftLink.h"
@@ -272,6 +273,26 @@
{
}
+ std::optional<ByteRange> byteRangeForAttachment(CFStringRef key) const
+ {
+ auto byteOffsetCF = dynamic_cf_cast<CFNumberRef>(PAL::CMGetAttachment(m_sample.get(), key, nullptr));
+ if (!byteOffsetCF)
+ return std::nullopt;
+
+ int64_t byteOffset = 0;
+ if (!CFNumberGetValue(byteOffsetCF, kCFNumberSInt64Type, &byteOffset))
+ return std::nullopt;
+
+ CMItemCount sizeArrayEntries = 0;
+ PAL::CMSampleBufferGetSampleSizeArray(m_sample.get(), 0, nullptr, &sizeArrayEntries);
+ if (sizeArrayEntries != 1)
+ return std::nullopt;
+
+ size_t singleSizeEntry = 0;
+ PAL::CMSampleBufferGetSampleSizeArray(m_sample.get(), 1, &singleSizeEntry, nullptr);
+ return { { CheckedSize(byteOffset), singleSizeEntry } };
+ }
+
RetainPtr<CGImageRef> m_image;
bool m_hasAlpha { false };
};
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.h (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -64,7 +64,6 @@
SampleFlags flags() const override;
PlatformSample platformSample() const override;
PlatformSample::Type platformSampleType() const override { return PlatformSample::CMSampleBufferType; }
- std::optional<ByteRange> byteRange() const override;
void offsetTimestampsBy(const MediaTime&) override;
void setTimestamps(const MediaTime&, const MediaTime&) override;
WEBCORE_EXPORT bool isDivisable() const override;
@@ -82,8 +81,6 @@
bool isHomogeneous() const;
Vector<Ref<MediaSampleAVFObjC>> divideIntoHomogeneousSamples();
- void setByteRangeOffset(size_t);
-
#if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION)
using KeyIDs = Vector<Ref<FragmentedSharedBuffer>>;
void setKeyIDs(KeyIDs&& keyIDs) { m_keyIDs = WTFMove(keyIDs); }
@@ -101,8 +98,6 @@
WEBCORE_EXPORT MediaSampleAVFObjC(CMSampleBufferRef, VideoRotation, bool mirrored);
WEBCORE_EXPORT virtual ~MediaSampleAVFObjC();
- std::optional<MediaSample::ByteRange> byteRangeForAttachment(CFStringRef key) const;
-
RetainPtr<CMSampleBufferRef> m_sample;
AtomString m_id;
VideoRotation m_rotation { VideoRotation::None };
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2022-03-09 07:38:58 UTC (rev 291033)
@@ -505,44 +505,6 @@
return adoptCF(newSampleBuffer);
}
-static CFStringRef byteRangeOffsetAttachmentKey()
-{
- static CFStringRef key = CFSTR("WebKitMediaSampleByteRangeOffset");
- return key;
-}
-
-std::optional<MediaSample::ByteRange> MediaSampleAVFObjC::byteRange() const
-{
- return byteRangeForAttachment(byteRangeOffsetAttachmentKey());
-}
-
-void MediaSampleAVFObjC::setByteRangeOffset(size_t byteOffset)
-{
- int64_t checkedOffset = CheckedInt64(byteOffset);
- auto offsetNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &checkedOffset));
- PAL::CMSetAttachment(m_sample.get(), byteRangeOffsetAttachmentKey(), offsetNumber.get(), kCMAttachmentMode_ShouldPropagate);
-}
-
-std::optional<MediaSample::ByteRange> MediaSampleAVFObjC::byteRangeForAttachment(CFStringRef key) const
-{
- auto byteOffsetCF = dynamic_cf_cast<CFNumberRef>(PAL::CMGetAttachment(m_sample.get(), key, nullptr));
- if (!byteOffsetCF)
- return std::nullopt;
-
- int64_t byteOffset = 0;
- if (!CFNumberGetValue(byteOffsetCF, kCFNumberSInt64Type, &byteOffset))
- return std::nullopt;
-
- CMItemCount sizeArrayEntries = 0;
- PAL::CMSampleBufferGetSampleSizeArray(m_sample.get(), 0, nullptr, &sizeArrayEntries);
- if (sizeArrayEntries != 1)
- return std::nullopt;
-
- size_t singleSizeEntry = 0;
- PAL::CMSampleBufferGetSampleSizeArray(m_sample.get(), 1, &singleSizeEntry, nullptr);
- return { { CheckedSize(byteOffset), singleSizeEntry } };
-}
-
CVPixelBufferRef MediaSampleAVFObjC::pixelBuffer() const
{
return static_cast<CVPixelBufferRef>(PAL::CMSampleBufferGetImageBuffer(m_sample.get()));
Modified: trunk/Source/WebCore/platform/graphics/cocoa/CMUtilities.h (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/cocoa/CMUtilities.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/cocoa/CMUtilities.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -41,7 +41,7 @@
WEBCORE_EXPORT RetainPtr<CMFormatDescriptionRef> createFormatDescriptionFromTrackInfo(const TrackInfo&);
// Convert MediaSamplesBlock to the equivalent CMSampleBufferRef. If CMFormatDescriptionRef
// is set it will be used, otherwise it will be created from the MediaSamplesBlock's TrackInfo.
-WEBCORE_EXPORT Expected<RetainPtr<CMSampleBufferRef>, CString> toCMSampleBuffer(MediaSamplesBlock&&, CMFormatDescriptionRef);
+WEBCORE_EXPORT Expected<RetainPtr<CMSampleBufferRef>, CString> toCMSampleBuffer(MediaSamplesBlock&&, CMFormatDescriptionRef = nullptr);
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -536,9 +536,7 @@
{
}
-WebMParser::~WebMParser()
-{
-}
+WebMParser::~WebMParser() = default;
void WebMParser::resetState()
{
@@ -560,6 +558,13 @@
m_parser->DidSeek();
}
+void WebMParser::createByteRangeSamples()
+{
+ for (auto& track : m_tracks)
+ track->createByteRangeSamples();
+ m_createByteRangeSamples = true;
+}
+
ExceptionOr<int> WebMParser::parse(SourceBufferParser::Segment&& segment)
{
if (!m_parser)
@@ -851,32 +856,30 @@
}
StringView codecString { trackEntry.codec_id.value().data(), (unsigned)trackEntry.codec_id.value().length() };
+ auto track = [&]() -> UniqueRef<TrackData> {
#if ENABLE(VP9)
- if (codecString == "V_VP9" && isVP9DecoderAvailable()) {
- m_tracks.append(VideoTrackData::create(CodecType::VP9, trackEntry, *this));
- return Status(Status::kOkCompleted);
- }
- if (codecString == "V_VP8" && isVP8DecoderAvailable()) {
- m_tracks.append(VideoTrackData::create(CodecType::VP8, trackEntry, *this));
- return Status(Status::kOkCompleted);
- }
+ if (codecString == "V_VP9" && isVP9DecoderAvailable())
+ return VideoTrackData::create(CodecType::VP9, trackEntry, *this);
+ if (codecString == "V_VP8" && isVP8DecoderAvailable())
+ return VideoTrackData::create(CodecType::VP8, trackEntry, *this);
#endif
#if ENABLE(VORBIS)
- if (codecString == "A_VORBIS" && isVorbisDecoderAvailable()) {
- m_tracks.append(AudioTrackData::create(CodecType::Vorbis, trackEntry, *this));
- return Status(Status::kOkCompleted);
- }
+ if (codecString == "A_VORBIS" && isVorbisDecoderAvailable())
+ return AudioTrackData::create(CodecType::Vorbis, trackEntry, *this);
#endif
#if ENABLE(OPUS)
- if (codecString == "A_OPUS" && isOpusDecoderAvailable()) {
- m_tracks.append(AudioTrackData::create(CodecType::Opus, trackEntry, *this));
- return Status(Status::kOkCompleted);
- }
+ if (codecString == "A_OPUS" && isOpusDecoderAvailable())
+ return AudioTrackData::create(CodecType::Opus, trackEntry, *this);
#endif
+ return TrackData::create(CodecType::Unsupported, trackEntry, *this);
+ }();
- m_tracks.append(TrackData::create(CodecType::Unsupported, trackEntry, *this));
+ if (m_createByteRangeSamples)
+ track->createByteRangeSamples();
+
+ m_tracks.append(WTFMove(track));
return Status(Status::kOkCompleted);
}
@@ -1032,6 +1035,11 @@
return webm::Status(webm::Status::kOkPartial);
m_completeBlockBuffer = m_currentBlockBuffer.take();
+ if (m_useByteRange)
+ m_completeFrameData = MediaSample::ByteRange { metadata.position, metadata.size };
+ else
+ m_completeFrameData = Ref { *m_completeBlockBuffer };
+
m_completePacketSize = std::nullopt;
m_partialBytesRead = 0;
@@ -1051,10 +1059,8 @@
if (!status.completed_ok())
return status;
- m_lastPosition = metadata.position;
-
constexpr size_t maxHeaderSize = 32; // The maximum length of a VP9 uncompressed header is 144 bits and 11 bytes for VP8. Round high.
- size_t segmentHeaderLength = std::min(maxHeaderSize, m_completeBlockBuffer->size());
+ size_t segmentHeaderLength = std::min<size_t>(maxHeaderSize, metadata.size);
auto contiguousBuffer = contiguousCompleteBlockBuffer(0, segmentHeaderLength);
if (!contiguousBuffer) {
PARSER_LOG_ERROR_IF_POSSIBLE("VideoTrackData::consumeFrameData failed to create contiguous data block");
@@ -1090,7 +1096,7 @@
if (track.default_duration.is_present())
duration = track.default_duration.value() * presentationTime.timeScale() / k_us_in_seconds;
- m_completeMediaSamples.append({ presentationTime, presentationTime, MediaTime(duration, presentationTime.timeScale()), m_completeBlockBuffer.releaseNonNull(), isKey ? MediaSample::SampleFlags::IsSync : MediaSample::SampleFlags::None });
+ m_completeMediaSamples.append({ presentationTime, presentationTime, MediaTime(duration, presentationTime.timeScale()), WTFMove(m_completeFrameData), isKey ? MediaSample::SampleFlags::IsSync : MediaSample::SampleFlags::None });
drainPendingSamples();
@@ -1116,8 +1122,6 @@
if (!status.completed_ok())
return status;
- m_lastPosition = metadata.position;
-
if (!formatDescription()) {
if (!track().codec_private.is_present()) {
PARSER_LOG_ERROR_IF_POSSIBLE("Audio track missing magic cookie");
@@ -1180,7 +1184,7 @@
else if (formatDescription() && *formatDescription() != *m_completeMediaSamples.info())
drainPendingSamples();
- m_completeMediaSamples.append({ presentationTime, MediaTime::invalidTime(), m_packetDuration, m_completeBlockBuffer.releaseNonNull(), MediaSample::SampleFlags::IsSync });
+ m_completeMediaSamples.append({ presentationTime, MediaTime::invalidTime(), m_packetDuration, WTFMove(m_completeFrameData), MediaSample::SampleFlags::IsSync });
drainPendingSamples();
@@ -1299,9 +1303,9 @@
return nullptr;
}
-void WebMParser::provideMediaData(MediaSamplesBlock&& samples, uint64_t position)
+void WebMParser::provideMediaData(MediaSamplesBlock&& samples)
{
- m_callback.parsedMediaData(WTFMove(samples), position);
+ m_callback.parsedMediaData(WTFMove(samples));
}
void SourceBufferParserWebM::parsedInitializationData(InitializationSegment&& initializationSegment)
@@ -1312,7 +1316,7 @@
});
}
-void SourceBufferParserWebM::parsedMediaData(MediaSamplesBlock&& samplesBlock, uint64_t position)
+void SourceBufferParserWebM::parsedMediaData(MediaSamplesBlock&& samplesBlock)
{
if (!samplesBlock.info()) {
ERROR_LOG_IF_POSSIBLE(LOGIDENTIFIER, "No TrackInfo set");
@@ -1336,7 +1340,7 @@
}
if (samplesBlock.isVideo()) {
- returnSamples(WTFMove(samplesBlock), m_videoFormatDescription.get(), position);
+ returnSamples(WTFMove(samplesBlock), m_videoFormatDescription.get());
return;
}
@@ -1344,7 +1348,7 @@
if (m_queuedAudioSamples.size()) {
auto& lastSample = m_queuedAudioSamples.last();
if (lastSample.duration + lastSample.presentationTime != samplesBlock.first().presentationTime)
- flushPendingAudioSamples(position);
+ flushPendingAudioSamples();
}
for (auto& sample : samplesBlock)
m_queuedAudioDuration += sample.duration;
@@ -1351,10 +1355,10 @@
m_queuedAudioSamples.append(WTFMove(samplesBlock));
if (m_queuedAudioDuration < m_minimumAudioSampleDuration)
return;
- flushPendingAudioSamples(position);
+ flushPendingAudioSamples();
}
-void SourceBufferParserWebM::returnSamples(MediaSamplesBlock&& block, CMFormatDescriptionRef description, std::optional<uint64_t> position)
+void SourceBufferParserWebM::returnSamples(MediaSamplesBlock&& block, CMFormatDescriptionRef description)
{
if (block.isEmpty())
return;
@@ -1365,13 +1369,11 @@
return;
}
- m_callOnClientThreadCallback([this, protectedThis = Ref { *this }, trackID = block.info()->trackID, sampleBuffer = WTFMove(expectedBuffer.value()), position] () mutable {
+ m_callOnClientThreadCallback([this, protectedThis = Ref { *this }, trackID = block.info()->trackID, sampleBuffer = WTFMove(expectedBuffer.value())] () mutable {
if (!m_didProvideMediaDataCallback)
return;
auto mediaSample = MediaSampleAVFObjC::create(sampleBuffer.get(), trackID);
- if (position)
- mediaSample->setByteRangeOffset(*position);
m_didProvideMediaDataCallback(WTFMove(mediaSample), trackID, emptyString());
});
@@ -1391,13 +1393,13 @@
m_didProvideContentKeyRequestInitializationDataForTrackIDCallback(WTFMove(keyID), trackID);
}
-void SourceBufferParserWebM::flushPendingAudioSamples(std::optional<uint64_t> position)
+void SourceBufferParserWebM::flushPendingAudioSamples()
{
if (!m_audioFormatDescription)
return;
ASSERT(m_audioInfo);
m_queuedAudioSamples.setInfo(m_audioInfo.copyRef());
- returnSamples(WTFMove(m_queuedAudioSamples), m_audioFormatDescription.get(), position);
+ returnSamples(WTFMove(m_queuedAudioSamples), m_audioFormatDescription.get());
m_queuedAudioSamples = { };
m_queuedAudioDuration = { };
Modified: trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -28,6 +28,7 @@
#if ENABLE(MEDIA_SOURCE)
#include "ExceptionOr.h"
+#include "MediaSample.h"
#include "SharedBuffer.h"
#include "SourceBufferParser.h"
#include <CoreAudio/CoreAudioTypes.h>
@@ -52,30 +53,30 @@
WTF_MAKE_FAST_ALLOCATED;
public:
class Callback {
- WTF_MAKE_FAST_ALLOCATED;
public:
virtual void parsedTrimmingData(uint64_t, const MediaTime&) { }
virtual void parsedInitializationData(SourceBufferParser::InitializationSegment&&) = 0;
- virtual void parsedMediaData(MediaSamplesBlock&&, uint64_t) = 0;
+ virtual void parsedMediaData(MediaSamplesBlock&&) = 0;
virtual bool canDecrypt() const { return false; }
virtual void contentKeyRequestInitializationDataForTrackID(Ref<SharedBuffer>&&, uint64_t) { }
virtual ~Callback() = default;
};
- WebMParser(Callback&);
- ~WebMParser();
+ WEBCORE_EXPORT WebMParser(Callback&);
+ WEBCORE_EXPORT ~WebMParser();
class SegmentReader;
- ExceptionOr<int> parse(SourceBufferParser::Segment&&);
- void resetState();
- void reset();
- void invalidate();
+ WEBCORE_EXPORT void createByteRangeSamples();
+ WEBCORE_EXPORT ExceptionOr<int> parse(SourceBufferParser::Segment&&);
+ WEBCORE_EXPORT void resetState();
+ WEBCORE_EXPORT void reset();
+ WEBCORE_EXPORT void invalidate();
const webm::Status& status() const { return m_status; }
- void provideMediaData(MediaSamplesBlock&&, uint64_t);
+ void provideMediaData(MediaSamplesBlock&&);
- void setLogger(const Logger&, const void* identifier);
+ WEBCORE_EXPORT void setLogger(const Logger&, const void* identifier);
const Logger* loggerPtr() const { return m_logger.get(); }
const void* logIdentifier() const { return m_logIdentifier; }
@@ -134,6 +135,8 @@
webm::TrackEntry& track() { return m_track; }
TrackInfo::TrackType trackType() const { return m_trackType; }
+ void createByteRangeSamples() { m_useByteRange = true; }
+
RefPtr<TrackInfo> formatDescription() const { return m_formatDescription.copyRef(); }
void setFormatDescription(Ref<TrackInfo>&& description)
{
@@ -167,7 +170,7 @@
{
if (!m_completeMediaSamples.size())
return;
- m_parser.provideMediaData(WTFMove(m_completeMediaSamples), m_lastPosition);
+ m_parser.provideMediaData(WTFMove(m_completeMediaSamples));
resetCompletedFramesState();
}
@@ -174,9 +177,9 @@
protected:
RefPtr<SharedBuffer> contiguousCompleteBlockBuffer(size_t offset, size_t length) const;
webm::Status readFrameData(webm::Reader&, const webm::FrameMetadata&, uint64_t* bytesRemaining);
- RefPtr<FragmentedSharedBuffer> m_completeBlockBuffer;
MediaSamplesBlock m_completeMediaSamples;
- uint64_t m_lastPosition { 0 };
+ bool m_useByteRange { false };
+ MediaSamplesBlock::MediaSampleDataType m_completeFrameData;
private:
CodecType m_codec;
@@ -184,6 +187,7 @@
const TrackInfo::TrackType m_trackType;
RefPtr<TrackInfo> m_formatDescription;
SharedBufferBuilder m_currentBlockBuffer;
+ RefPtr<const FragmentedSharedBuffer> m_completeBlockBuffer;
WebMParser& m_parser;
std::optional<size_t> m_completePacketSize;
// Size of the currently incomplete parsed packet.
@@ -279,6 +283,7 @@
const void* m_logIdentifier { nullptr };
uint64_t m_nextChildIdentifier { 0 };
Callback& m_callback;
+ bool m_createByteRangeSamples { false };
};
class SourceBufferParserWebM : public SourceBufferParser, WebMParser::Callback {
@@ -308,7 +313,7 @@
m_didParseTrimmingDataCallback = WTFMove(callback);
}
- void flushPendingAudioSamples(std::optional<uint64_t> = std::nullopt);
+ void flushPendingAudioSamples();
void setMinimumAudioSampleDuration(float);
WEBCORE_EXPORT void setLogger(const Logger&, const void* identifier) final;
@@ -318,13 +323,13 @@
private:
// WebMParser::Callback
void parsedInitializationData(SourceBufferParser::InitializationSegment&&) final;
- void parsedMediaData(MediaSamplesBlock&&, uint64_t) final;
+ void parsedMediaData(MediaSamplesBlock&&) final;
bool canDecrypt() const final { return !!m_didProvideContentKeyRequestInitializationDataForTrackIDCallback; }
void contentKeyRequestInitializationDataForTrackID(Ref<SharedBuffer>&&, uint64_t) final;
void parsedTrimmingData(uint64_t, const MediaTime&) final;
-
- void returnSamples(MediaSamplesBlock&&, CMFormatDescriptionRef, std::optional<uint64_t>);
+ void returnSamples(MediaSamplesBlock&&, CMFormatDescriptionRef);
+
DidParseTrimmingDataCallback m_didParseTrimmingDataCallback;
WebMParser m_parser;
RetainPtr<CMFormatDescriptionRef> m_audioFormatDescription;
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.h (291032 => 291033)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaSampleGStreamer.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -61,7 +61,6 @@
SampleFlags flags() const override { return m_flags; }
PlatformSample platformSample() const override;
PlatformSample::Type platformSampleType() const override { return PlatformSample::GStreamerSampleType; }
- std::optional<ByteRange> byteRange() const override { return std::nullopt; }
void dump(PrintStream&) const override;
RefPtr<JSC::Uint8ClampedArray> getRGBAImageData() const final;
VideoRotation videoRotation() const override { return m_videoRotation; }
Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp (291032 => 291033)
--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -62,7 +62,6 @@
SampleFlags flags() const override;
PlatformSample platformSample() const override;
PlatformSample::Type platformSampleType() const override { return PlatformSample::MockSampleBoxType; }
- std::optional<ByteRange> byteRange() const override { return std::nullopt; }
FloatSize presentationSize() const override { return FloatSize(); }
void dump(PrintStream&) const override;
void offsetTimestampsBy(const MediaTime& offset) override { m_box.offsetTimestampsBy(offset); }
Modified: trunk/Source/WebKit/ChangeLog (291032 => 291033)
--- trunk/Source/WebKit/ChangeLog 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/ChangeLog 2022-03-09 07:38:58 UTC (rev 291033)
@@ -1,3 +1,49 @@
+2022-03-08 Jean-Yves Avenard <j...@apple.com>
+
+ Have MediaFormatReader plugin use WebMParser directly
+ https://bugs.webkit.org/show_bug.cgi?id=237594
+ rdar://89960307
+
+ Reviewed by Eric Carlson.
+
+ Directly build the sample tables from the sample's offset/size without
+ first build MediaSampleAVFObjC objects.
+ The MTPluginByteSourceRef interface unfortunately doesn't allow to skip a
+ given number of bytes, and you must read the content into a buffer to be
+ able to continue reading the resource.
+ As such, we continue to have to create SharedBuffer objects for each sample.
+ However, those objects are now much shorter lived and not dispatched to
+ other work queues. So the peak memory usage when playing a webm is
+ significantly reduced: a 50% memory reduction (from 440MB to 202MB with a sample video)
+
+ * Shared/mac/MediaFormatReader/MediaFormatReader.cpp:
+ (WebKit::MediaFormatReader::parseByteSource):
+ (WebKit::MediaFormatReader::parsedInitializationData):
+ (WebKit::MediaFormatReader::parsedMediaData):
+ (WebKit::MediaFormatReader::didProvideMediaData):
+ (WebKit::MediaFormatReader::finishParsing):
+ * Shared/mac/MediaFormatReader/MediaFormatReader.h:
+ * Shared/mac/MediaFormatReader/MediaSampleByteRange.cpp:
+ (WebKit::MediaSampleByteRange::MediaSampleByteRange):
+ (WebKit::MediaSampleByteRange::trackID const):
+ (WebKit::MediaSampleByteRange::platformSample const):
+ (WebKit::MediaSampleByteRange::presentationTime const):
+ (WebKit::MediaSampleByteRange::decodeTime const):
+ (WebKit::MediaSampleByteRange::duration const):
+ (WebKit::MediaSampleByteRange::sizeInBytes const):
+ (WebKit::MediaSampleByteRange::presentationSize const):
+ (WebKit::MediaSampleByteRange::flags const):
+ (WebKit::MediaSampleByteRange::byteRange const):
+ (WebKit::MediaSampleByteRange::offsetTimestampsBy):
+ (WebKit::MediaSampleByteRange::setTimestamps):
+ * Shared/mac/MediaFormatReader/MediaSampleByteRange.h:
+ * Shared/mac/MediaFormatReader/MediaSampleCursor.cpp:
+ (WebKit::MediaSampleCursor::copyFormatDescription const):
+ * Shared/mac/MediaFormatReader/MediaTrackReader.cpp:
+ (WebKit::MediaTrackReader::addSample):
+ (WebKit::MediaTrackReader::copyProperty):
+ * Shared/mac/MediaFormatReader/MediaTrackReader.h:
+
2022-03-08 John Cunningham <johncunning...@apple.com>
RemoteGraphicsContextGL ReadPixels does not preserve contents for area that is not part of the Framebuffer
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.cpp (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -132,14 +132,6 @@
{
ASSERT(isMainRunLoop());
- static NeverDestroyed<ContentType> contentType("video/webm"_s);
- auto parser = SourceBufferParserWebM::create(contentType);
- if (!parser) {
- Locker locker { m_parseTracksLock };
- m_parseTracksStatus = kMTPluginFormatReaderError_AllocationFailure;
- return;
- }
-
if (!m_logger) {
m_logger = &Document::sharedLogger();
m_logIdentifier = nextLogIdentifier();
@@ -146,27 +138,7 @@
}
ALWAYS_LOG_IF_POSSIBLE(LOGIDENTIFIER);
- parser->setLogger(*m_logger, m_logIdentifier);
- // Set a minimum audio sample duration of 0 so the parser creates indivisible samples with byte source ranges.
- parser->setMinimumAudioSampleDuration(0);
-
- parser->setCallOnClientThreadCallback([](Function<void()>&& function) {
- MediaTrackReader::storageQueue().dispatch(WTFMove(function));
- });
-
- parser->setDidParseInitializationDataCallback([this, protectedThis = Ref { *this }](SourceBufferParser::InitializationSegment&& initializationSegment) {
- didParseTracks(WTFMove(initializationSegment), noErr);
- });
-
- parser->setDidEncounterErrorDuringParsingCallback([this, protectedThis = Ref { *this }](uint64_t errorCode) {
- didParseTracks({ }, errorCode);
- });
-
- parser->setDidProvideMediaDataCallback([this, protectedThis = Ref { *this }](Ref<MediaSampleAVFObjC>&& mediaSample, uint64_t trackID, const String& mediaType) {
- didProvideMediaData(WTFMove(mediaSample), trackID, mediaType);
- });
-
Locker locker { m_parseTracksLock };
m_byteSource = WTFMove(byteSource);
m_parseTracksStatus = std::nullopt;
@@ -173,14 +145,34 @@
m_duration = MediaTime::invalidTime();
m_trackReaders.clear();
- readerQueue().dispatch([this, protectedThis = Ref { *this }, byteSource = m_byteSource, parser = parser.releaseNonNull()]() mutable {
- parser->appendData(WTFMove(byteSource));
- MediaTrackReader::storageQueue().dispatch([this, protectedThis = Ref { *this }, parser = WTFMove(parser)]() mutable {
- finishParsing(WTFMove(parser));
+ // FIXME: why do we need a storage queue different to reader's queue?
+ readerQueue().dispatch([this, protectedThis = Ref { *this }, byteSource = m_byteSource]() mutable {
+ WebMParser parser(*this);
+ parser.setLogger(*m_logger, m_logIdentifier);
+ parser.createByteRangeSamples();
+ auto result = parser.parse(WTFMove(byteSource));
+ MediaTrackReader::storageQueue().dispatch([this, protectedThis = Ref { *this }, result] () mutable {
+ if (!result.hasException() && result.returnValue())
+ didParseTracks({ }, result.returnValue());
+ finishParsing();
});
});
}
+void MediaFormatReader::parsedInitializationData(SourceBufferParser::InitializationSegment&& initializationSegment)
+{
+ MediaTrackReader::storageQueue().dispatch([this, protectedThis = Ref { *this }, initializationSegment = WTFMove(initializationSegment)] () mutable {
+ didParseTracks(WTFMove(initializationSegment), noErr);
+ });
+}
+
+void MediaFormatReader::parsedMediaData(MediaSamplesBlock&& mediaSamples)
+{
+ MediaTrackReader::storageQueue().dispatch([this, protectedThis = Ref { *this }, mediaSamples = WTFMove(mediaSamples)] () mutable {
+ didProvideMediaData(WTFMove(mediaSamples));
+ });
+}
+
void MediaFormatReader::didParseTracks(SourceBufferPrivateClient::InitializationSegment&& segment, uint64_t errorCode)
{
ASSERT(!isMainRunLoop());
@@ -225,20 +217,20 @@
m_init = true;
}
-void MediaFormatReader::didProvideMediaData(Ref<MediaSampleAVFObjC>&& mediaSample, uint64_t trackID, const String&)
+void MediaFormatReader::didProvideMediaData(MediaSamplesBlock&& mediaSamples)
{
ASSERT(!isMainRunLoop());
Locker locker { m_parseTracksLock };
auto trackIndex = m_trackReaders.findIf([&](auto& track) {
- return track->trackID() == trackID;
+ return track->trackID() == mediaSamples.info()->trackID;
});
if (trackIndex != notFound)
- m_trackReaders[trackIndex]->addSample(WTFMove(mediaSample), m_byteSource.get());
+ m_trackReaders[trackIndex]->addSample(WTFMove(mediaSamples), m_byteSource.get());
}
-void MediaFormatReader::finishParsing(Ref<SourceBufferParser>&& parser)
+void MediaFormatReader::finishParsing()
{
ASSERT(!isMainRunLoop());
ALWAYS_LOG_IF_POSSIBLE(LOGIDENTIFIER);
@@ -258,11 +250,6 @@
if (greatestPresentationTime.isValid())
m_duration = greatestPresentationTime;
}
-
- parser->setDidParseInitializationDataCallback(nullptr);
- parser->setDidEncounterErrorDuringParsingCallback(nullptr);
- parser->setDidProvideMediaDataCallback(nullptr);
- parser->resetParserState();
}
OSStatus MediaFormatReader::copyProperty(CFStringRef key, CFAllocatorRef allocator, void* valueCopy)
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.h (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaFormatReader.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -28,6 +28,7 @@
#if ENABLE(WEBM_FORMAT_READER)
#include "CoreMediaWrapped.h"
+#include <WebCore/SourceBufferParserWebM.h>
#include <WebCore/SourceBufferPrivateClient.h>
#include <wtf/Condition.h>
#include <wtf/Lock.h>
@@ -36,8 +37,8 @@
DECLARE_CORE_MEDIA_TRAITS(FormatReader);
namespace WebCore {
-class MediaSampleAVFObjC;
-class SourceBufferParser;
+class MediaSamplesBlock;
+class WebMParser;
}
namespace WebKit {
@@ -44,7 +45,7 @@
class MediaTrackReader;
-class MediaFormatReader final : public CoreMediaWrapped<MediaFormatReader> {
+class MediaFormatReader final : public CoreMediaWrapped<MediaFormatReader> , public WebCore::WebMParser::Callback {
public:
using CoreMediaWrapped<MediaFormatReader>::unwrap;
@@ -64,12 +65,16 @@
private:
explicit MediaFormatReader(Allocator&&);
+ // WebMParser::Callback
+ void parsedInitializationData(WebCore::SourceBufferParser::InitializationSegment&&) final;
+ void parsedMediaData(WebCore::MediaSamplesBlock&&) final;
+
void parseByteSource(RetainPtr<MTPluginByteSourceRef>&&);
void didParseTracks(WebCore::SourceBufferPrivateClient::InitializationSegment&&, uint64_t errorCode);
void didSelectVideoTrack(WebCore::VideoTrackPrivate&, bool) { }
void didEnableAudioTrack(WebCore::AudioTrackPrivate&, bool) { }
- void didProvideMediaData(Ref<WebCore::MediaSampleAVFObjC>&&, uint64_t, const String&);
- void finishParsing(Ref<WebCore::SourceBufferParser>&&);
+ void didProvideMediaData(WebCore::MediaSamplesBlock&&);
+ void finishParsing();
// CMBaseClass
String debugDescription() const final { return "WebKit::MediaFormatReader"_s; }
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.cpp (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -33,57 +33,75 @@
using namespace WebCore;
-MediaSampleByteRange::MediaSampleByteRange(MediaSample& sample, MTPluginByteSourceRef byteSource, uint64_t trackID)
- : m_presentationTime(sample.presentationTime())
- , m_decodeTime(sample.decodeTime())
- , m_duration(sample.duration())
- , m_byteRange(*sample.byteRange())
- , m_trackID(trackID)
- , m_sizeInBytes(sample.sizeInBytes())
- , m_presentationSize(sample.presentationSize())
+MediaSampleByteRange::MediaSampleByteRange(MediaSamplesBlock&& sample, MTPluginByteSourceRef byteSource)
+ : m_block(WTFMove(sample))
, m_byteSource(byteSource)
- , m_flags(sample.flags())
{
- ASSERT(!isMainRunLoop());
- ASSERT(m_decodeTime == m_presentationTime || m_decodeTime == MediaTime::invalidTime());
- auto platformSample = sample.platformSample();
- switch (platformSample.type) {
- case PlatformSample::CMSampleBufferType:
- m_formatDescription = PAL::CMSampleBufferGetFormatDescription(platformSample.sample.cmSampleBuffer);
- break;
- case PlatformSample::ByteRangeSampleType:
- m_formatDescription = platformSample.sample.byteRangeSample.second;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
+ ASSERT(!m_block.isEmpty());
+ ASSERT(std::holds_alternative<MediaSample::ByteRange>(m_block.last().data));
}
AtomString MediaSampleByteRange::trackID() const
{
- return AtomString::number(m_trackID);
+ return AtomString::number(m_block.info()->trackID);
}
PlatformSample MediaSampleByteRange::platformSample() const
{
+ ASSERT(m_block.info());
return {
PlatformSample::ByteRangeSampleType,
- { .byteRangeSample = std::make_pair(m_byteSource.get(), m_formatDescription.get()) },
+ { .byteRangeSample = std::make_pair(m_byteSource.get(), std::reference_wrapper(*m_block.info())) },
};
}
-void MediaSampleByteRange::offsetTimestampsBy(const MediaTime& offset)
+MediaTime MediaSampleByteRange::presentationTime() const
{
- setTimestamps(presentationTime() + offset, decodeTime() + offset);
+ return m_block.last().presentationTime;
}
-void MediaSampleByteRange::setTimestamps(const MediaTime& presentationTime, const MediaTime& decodeTime)
+MediaTime MediaSampleByteRange::decodeTime() const
{
- m_presentationTime = presentationTime;
- m_decodeTime = decodeTime;
+ return m_block.last().decodeTime;
}
+MediaTime MediaSampleByteRange::duration() const
+{
+ return m_block.last().duration;
+}
+
+size_t MediaSampleByteRange::sizeInBytes() const
+{
+ return std::get<MediaSample::ByteRange>(m_block.last().data).byteLength;
+}
+
+WebCore::FloatSize MediaSampleByteRange::presentationSize() const
+{
+ if (m_block.isVideo())
+ return downcast<const VideoInfo>(m_block.info())->displaySize;
+ return { };
+}
+
+MediaSampleByteRange::SampleFlags MediaSampleByteRange::flags() const
+{
+ return m_block.last().flags;
+}
+
+std::optional<MediaSampleByteRange::ByteRange> MediaSampleByteRange::byteRange() const
+{
+ return std::get<MediaSample::ByteRange>(m_block.last().data);
+}
+
+void MediaSampleByteRange::offsetTimestampsBy(const MediaTime&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void MediaSampleByteRange::setTimestamps(const MediaTime&, const MediaTime&)
+{
+ ASSERT_NOT_REACHED();
+}
+
} // namespace WebKit
#endif // ENABLE(WEBM_FORMAT_READER)
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.h (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleByteRange.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -27,27 +27,24 @@
#if ENABLE(WEBM_FORMAT_READER)
-#include <WebCore/MediaSampleAVFObjC.h>
-#include <pal/spi/cocoa/MediaToolboxSPI.h>
-#include <wtf/MediaTime.h>
-#include <wtf/RetainPtr.h>
+#include <WebCore/MediaSample.h>
namespace WebKit {
class MediaSampleByteRange final : public WebCore::MediaSample {
public:
- static Ref<MediaSampleByteRange> create(WebCore::MediaSample& sample, MTPluginByteSourceRef byteSource, uint64_t trackID)
+ static Ref<MediaSampleByteRange> create(WebCore::MediaSamplesBlock&& sample, MTPluginByteSourceRef byteSource)
{
- return adoptRef(*new MediaSampleByteRange(sample, byteSource, trackID));
+ return adoptRef(*new MediaSampleByteRange(WTFMove(sample), byteSource));
}
- MediaTime presentationTime() const final { return m_presentationTime; }
- MediaTime decodeTime() const final { return m_decodeTime; }
- MediaTime duration() const final { return m_duration; }
- size_t sizeInBytes() const final { return m_sizeInBytes; }
- WebCore::FloatSize presentationSize() const final { return m_presentationSize; }
- SampleFlags flags() const final { return m_flags; }
- std::optional<ByteRange> byteRange() const final { return m_byteRange; }
+ MediaTime presentationTime() const final;
+ MediaTime decodeTime() const final;
+ MediaTime duration() const final;
+ size_t sizeInBytes() const final;
+ WebCore::FloatSize presentationSize() const final;
+ SampleFlags flags() const final;
+ std::optional<ByteRange> byteRange() const final;
AtomString trackID() const final;
WebCore::PlatformSample platformSample() const final;
@@ -54,21 +51,13 @@
WebCore::PlatformSample::Type platformSampleType() const final { return WebCore::PlatformSample::ByteRangeSampleType; }
void offsetTimestampsBy(const MediaTime&) final;
void setTimestamps(const MediaTime&, const MediaTime&) final;
- Ref<MediaSample> createNonDisplayingCopy() const { return *const_cast<MediaSampleByteRange*>(this); }
+ Ref<MediaSample> createNonDisplayingCopy() const final { return *const_cast<MediaSampleByteRange*>(this); }
private:
- MediaSampleByteRange(MediaSample&, MTPluginByteSourceRef, uint64_t trackID);
+ MediaSampleByteRange(WebCore::MediaSamplesBlock&&, MTPluginByteSourceRef);
- MediaTime m_presentationTime;
- MediaTime m_decodeTime;
- MediaTime m_duration;
- ByteRange m_byteRange;
- uint64_t m_trackID;
- size_t m_sizeInBytes;
- WebCore::FloatSize m_presentationSize;
+ const WebCore::MediaSamplesBlock m_block;
RetainPtr<MTPluginByteSourceRef> m_byteSource;
- RetainPtr<CMFormatDescriptionRef> m_formatDescription;
- SampleFlags m_flags;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleCursor.cpp (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleCursor.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaSampleCursor.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -30,6 +30,7 @@
#include "Logging.h"
#include "MediaTrackReader.h"
+#include <WebCore/CMUtilities.h>
#include <WebCore/MediaSample.h>
#include <WebCore/SampleMap.h>
#include <pal/avfoundation/MediaTimeAVFoundation.h>
@@ -348,19 +349,11 @@
OSStatus MediaSampleCursor::getSyncInfo(MTPluginSampleCursorSyncInfo* syncInfo) const
{
- OSStatus syncInfoStatus = noErr;
- auto getSampleStatus = getMediaSample([&](MediaSample& sample) {
- if (sample.hasSyncInfo()) {
- *syncInfo = {
- .fullSync = sample.isSync()
- };
- return;
- }
- syncInfoStatus = kCMBaseObjectError_ValueNotAvailable;
+ return getMediaSample([&](MediaSample& sample) {
+ *syncInfo = {
+ .fullSync = sample.isSync()
+ };
});
- if (syncInfoStatus != noErr)
- return syncInfoStatus;
- return getSampleStatus;
}
OSStatus MediaSampleCursor::copyFormatDescription(CMFormatDescriptionRef* formatDescriptionOut) const
@@ -367,7 +360,7 @@
{
return getMediaSample([&](MediaSample& sample) {
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(sample.platformSample().type == PlatformSample::ByteRangeSampleType);
- *formatDescriptionOut = retainPtr(sample.platformSample().sample.byteRangeSample.second).leakRef();
+ *formatDescriptionOut = createFormatDescriptionFromTrackInfo(sample.platformSample().sample.byteRangeSample.second).leakRef();
});
}
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.cpp (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -33,6 +33,7 @@
#include "MediaSampleByteRange.h"
#include "MediaSampleCursor.h"
#include <WebCore/AudioTrackPrivate.h>
+#include <WebCore/CMUtilities.h>
#include <WebCore/InbandTextTrackPrivate.h>
#include <WebCore/MediaDescription.h>
#include <WebCore/SampleMap.h>
@@ -97,7 +98,7 @@
return lastSample.presentationTime() + lastSample.duration();
}
-void MediaTrackReader::addSample(Ref<MediaSample>&& sample, MTPluginByteSourceRef byteSource)
+void MediaTrackReader::addSample(MediaSamplesBlock&& sample, MTPluginByteSourceRef byteSource)
{
ASSERT(!isMainRunLoop());
Locker locker { m_sampleStorageLock };
@@ -104,9 +105,11 @@
if (!m_sampleStorage)
m_sampleStorage = makeUnique<SampleStorage>();
- ASSERT(!sample->isDivisable() && sample->byteRange());
- auto sampleToAdd = MediaSampleByteRange::create(sample.get(), byteSource, m_trackID);
+ ASSERT(!sample.isEmpty());
+ ASSERT(std::holds_alternative<MediaSample::ByteRange>(sample.last().data));
+ auto sampleToAdd = MediaSampleByteRange::create(WTFMove(sample), byteSource);
+
// FIXME: Even though WebM muxer guidelines say this must not happen, some video tracks have two
// consecutive frames with the same presentation time. SampleMap will not store the second frame
// in these cases, corrupting all subsequent non-key frames. Find a way to store frames with
@@ -185,7 +188,15 @@
if (CFEqual(key, PAL::get_MediaToolbox_kMTPluginTrackReaderProperty_FormatDescriptionArray())) {
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(lastSample.platformSample().type == PlatformSample::ByteRangeSampleType);
- const void* descriptions[1] = { lastSample.platformSample().sample.byteRangeSample.second };
+ const TrackInfo& trackInfo = lastSample.platformSample().sample.byteRangeSample.second;
+ if (!m_trackInfo) {
+ m_trackInfo = &lastSample.platformSample().sample.byteRangeSample.second.get();
+ m_formatDescription = WebCore::createFormatDescriptionFromTrackInfo(*m_trackInfo);
+ } else if (*m_trackInfo != trackInfo) {
+ m_trackInfo = &trackInfo;
+ m_formatDescription = WebCore::createFormatDescriptionFromTrackInfo(*m_trackInfo);
+ }
+ const void* descriptions[1] = { m_formatDescription.get() };
*reinterpret_cast<CFArrayRef*>(copiedValue) = adoptCF(CFArrayCreate(allocator, descriptions, 1, &kCFTypeArrayCallBacks)).leakRef();
return noErr;
}
Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.h (291032 => 291033)
--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.h 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/MediaTrackReader.h 2022-03-09 07:38:58 UTC (rev 291033)
@@ -41,7 +41,7 @@
namespace WebCore {
class AudioTrackPrivate;
class InbandTextTrackPrivate;
-class MediaSample;
+class MediaSamplesBlock;
class TrackPrivateBase;
class VideoTrackPrivate;
}
@@ -65,7 +65,7 @@
MediaTime greatestPresentationTime() const;
void setEnabled(bool enabled) { m_isEnabled = enabled ? Enabled::True : Enabled::False; }
- void addSample(Ref<WebCore::MediaSample>&&, MTPluginByteSourceRef);
+ void addSample(WebCore::MediaSamplesBlock&&, MTPluginByteSourceRef);
void waitForSample(Function<bool(WebCore::SampleMap&, bool)>&&) const;
void finishParsing();
@@ -111,6 +111,8 @@
mutable std::unique_ptr<SampleStorage> m_sampleStorage WTF_GUARDED_BY_LOCK(m_sampleStorageLock);
Ref<const Logger> m_logger;
const void* m_logIdentifier;
+ RetainPtr<CMFormatDescriptionRef> m_formatDescription;
+ RefPtr<const WebCore::TrackInfo> m_trackInfo;
};
constexpr MediaTrackReader::WrapperClass MediaTrackReader::wrapperClass()
Modified: trunk/Tools/ChangeLog (291032 => 291033)
--- trunk/Tools/ChangeLog 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Tools/ChangeLog 2022-03-09 07:38:58 UTC (rev 291033)
@@ -1,3 +1,13 @@
+2022-03-08 Jean-Yves Avenard <j...@apple.com>
+
+ Have MediaFormatReader plugin use WebMParser directly
+ https://bugs.webkit.org/show_bug.cgi?id=237594
+ rdar://89960307
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/Tests/WebCore/SampleMap.cpp:
+
2022-03-08 John Cunningham <johncunning...@apple.com>
RemoteGraphicsContextGL ReadPixels does not preserve contents for area that is not part of the Framebuffer
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp (291032 => 291033)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp 2022-03-09 06:49:50 UTC (rev 291032)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp 2022-03-09 07:38:58 UTC (rev 291033)
@@ -70,7 +70,6 @@
SampleFlags flags() const final { return m_flags; }
PlatformSample platformSample() const final { return { PlatformSample::None, { nullptr } }; }
PlatformSample::Type platformSampleType() const final { return PlatformSample::None; }
- std::optional<ByteRange> byteRange() const final { return std::nullopt; }
void dump(PrintStream&) const final { }