Modified: branches/safari-610-branch/Source/WebCore/ChangeLog (268089 => 268090)
--- branches/safari-610-branch/Source/WebCore/ChangeLog 2020-10-07 00:09:11 UTC (rev 268089)
+++ branches/safari-610-branch/Source/WebCore/ChangeLog 2020-10-07 00:09:14 UTC (rev 268090)
@@ -1,5 +1,56 @@
2020-10-06 Alan Coon <[email protected]>
+ Cherry-pick r267521. rdar://problem/70023915
+
+ REGRESSION (iOS/Safari 14): MediaRecorder produces invalid video files
+ https://bugs.webkit.org/show_bug.cgi?id=216832
+ <rdar://problem/69377550>
+
+ Reviewed by Eric Carlson.
+
+ Start the audio and video timestamps at zero.
+ Compute the audio timestamp based on the sample count and the video timestamp based
+ on the time at which the video sample is received.
+
+ Covered by manually testing Safari generated videos on VLC, Chrome and Firefox.
+
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h:
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm:
+ (WebCore::MediaRecorderPrivateWriter::initialize):
+ (WebCore::MediaRecorderPrivateWriter::startAssetWriter):
+ (WebCore::copySampleBufferWithCurrentTimeStamp):
+ (WebCore::MediaRecorderPrivateWriter::appendVideoSampleBuffer):
+ (WebCore::createAudioSampleBuffer):
+ (WebCore::MediaRecorderPrivateWriter::appendAudioSampleBuffer):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267521 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2020-09-24 Youenn Fablet <[email protected]>
+
+ REGRESSION (iOS/Safari 14): MediaRecorder produces invalid video files
+ https://bugs.webkit.org/show_bug.cgi?id=216832
+ <rdar://problem/69377550>
+
+ Reviewed by Eric Carlson.
+
+ Start the audio and video timestamps at zero.
+ Compute the audio timestamp based on the sample count and the video timestamp based
+ on the time at which the video sample is received.
+
+ Covered by manually testing Safari generated videos on VLC, Chrome and Firefox.
+
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h:
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm:
+ (WebCore::MediaRecorderPrivateWriter::initialize):
+ (WebCore::MediaRecorderPrivateWriter::startAssetWriter):
+ (WebCore::copySampleBufferWithCurrentTimeStamp):
+ (WebCore::MediaRecorderPrivateWriter::appendVideoSampleBuffer):
+ (WebCore::createAudioSampleBuffer):
+ (WebCore::MediaRecorderPrivateWriter::appendAudioSampleBuffer):
+
+2020-10-06 Alan Coon <[email protected]>
+
Cherry-pick r267366. rdar://problem/70023908
[iOS] MediaRecorder incorrect screen orientation handling
Modified: branches/safari-610-branch/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm (268089 => 268090)
--- branches/safari-610-branch/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm 2020-10-07 00:09:11 UTC (rev 268089)
+++ branches/safari-610-branch/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm 2020-10-07 00:09:14 UTC (rev 268090)
@@ -399,9 +399,8 @@
}
-static inline RetainPtr<CMSampleBufferRef> copySampleBufferWithCurrentTimeStamp(CMSampleBufferRef originalBuffer)
+static inline RetainPtr<CMSampleBufferRef> copySampleBufferWithCurrentTimeStamp(CMSampleBufferRef originalBuffer, CMTime startTime)
{
- CMTime startTime = CMClockGetTime(CMClockGetHostTimeClock());
CMItemCount count = 0;
CMSampleBufferGetSampleTimingInfoArray(originalBuffer, 0, nil, &count);
@@ -425,6 +424,7 @@
{
if (!m_firstVideoFrame) {
m_firstVideoFrame = true;
+ m_firstVideoSampleTime = CMClockGetTime(CMClockGetHostTimeClock());
if (sample.videoRotation() != MediaSample::VideoRotation::None || sample.videoMirrored()) {
auto videoTransform = CGAffineTransformMakeRotation(static_cast<int>(sample.videoRotation()) * M_PI / 180);
if (sample.videoMirrored())
@@ -432,8 +432,9 @@
m_videoAssetWriterInput.get().transform = videoTransform;
}
}
- // FIXME: We should not set the timestamps if they are already set.
- if (auto bufferWithCurrentTime = copySampleBufferWithCurrentTimeStamp(sample.platformSample().sample.cmSampleBuffer))
+
+ CMTime sampleTime = CMTimeSubtract(CMClockGetTime(CMClockGetHostTimeClock()), m_firstVideoSampleTime);
+ if (auto bufferWithCurrentTime = copySampleBufferWithCurrentTimeStamp(sample.platformSample().sample.cmSampleBuffer, sampleTime))
m_videoCompressor->addSampleBuffer(bufferWithCurrentTime.get());
}
@@ -449,7 +450,7 @@
return adoptCF(format);
}
-static inline RetainPtr<CMSampleBufferRef> createAudioSampleBuffer(const PlatformAudioData& data, const AudioStreamDescription& description, const WTF::MediaTime& time, size_t sampleCount)
+static inline RetainPtr<CMSampleBufferRef> createAudioSampleBuffer(const PlatformAudioData& data, const AudioStreamDescription& description, CMTime time, size_t sampleCount)
{
auto format = createAudioFormatDescription(description);
if (!format)
@@ -456,7 +457,7 @@
return nullptr;
CMSampleBufferRef sampleBuffer = nullptr;
- auto error = CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault, NULL, false, NULL, NULL, format.get(), sampleCount, toCMTime(time), NULL, &sampleBuffer);
+ auto error = CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault, NULL, false, NULL, NULL, format.get(), sampleCount, time, NULL, &sampleBuffer);
if (error) {
RELEASE_LOG_ERROR(MediaStream, "MediaRecorderPrivateWriter createAudioSampleBufferWithPacketDescriptions failed with %d", error);
return nullptr;
@@ -471,10 +472,11 @@
return buffer;
}
-void MediaRecorderPrivateWriter::appendAudioSampleBuffer(const PlatformAudioData& data, const AudioStreamDescription& description, const WTF::MediaTime& time, size_t sampleCount)
+void MediaRecorderPrivateWriter::appendAudioSampleBuffer(const PlatformAudioData& data, const AudioStreamDescription& description, const WTF::MediaTime&, size_t sampleCount)
{
- if (auto sampleBuffer = createAudioSampleBuffer(data, description, time, sampleCount))
+ if (auto sampleBuffer = createAudioSampleBuffer(data, description, m_currentAudioSampleTime, sampleCount))
m_audioCompressor->addSampleBuffer(sampleBuffer.get());
+ m_currentAudioSampleTime = CMTimeAdd(m_currentAudioSampleTime, toCMTime(MediaTime(sampleCount, description.sampleRate())));
}
void MediaRecorderPrivateWriter::finishedFlushingSamples()