Changeset 278158 in webkit
- Timestamp:
- May 27, 2021 3:19:17 AM (14 months ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-h264-profiles-expected.txt (added)
-
LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-h264-profiles.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp (modified) (1 diff)
-
Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h (modified) (1 diff)
-
Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm (modified) (3 diffs)
-
Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h (modified) (4 diffs)
-
Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r278155 r278158 1 2021-05-27 Youenn Fablet <youenn@apple.com> 2 3 Support H264 profiles in MediaRecorder 4 https://bugs.webkit.org/show_bug.cgi?id=226219 5 <rdar://78027944> 6 7 Reviewed by Eric Carlson. 8 9 * http/wpt/mediarecorder/MediaRecorder-video-h264-profiles-expected.txt: Added. 10 * http/wpt/mediarecorder/MediaRecorder-video-h264-profiles.html: Added. 11 1 12 2021-05-27 Kimmo Kinnunen <kkinnunen@apple.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r278154 r278158 1 2021-05-27 Youenn Fablet <youenn@apple.com> 2 3 Support H264 profiles in MediaRecorder 4 https://bugs.webkit.org/show_bug.cgi?id=226219 5 <rdar://78027944> 6 7 Reviewed by Eric Carlson. 8 9 Use mimeType option given in MediaRecorder options to detect which H264 profile to use. 10 Implement this by parsing the mime type codec parameter and use the avc1.WXYZ string to compute the profile. 11 By default, use baseline profile, which is not VideoToolbox profile but has wider decoding support. 12 If profile specified by the application fails, we downgrade to baseline. 13 14 Test: http/wpt/mediarecorder/MediaRecorder-video-h264-profiles.html 15 16 * Modules/mediarecorder/MediaRecorderProvider.cpp: 17 (WebCore::MediaRecorderProvider::isSupported): 18 * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h: 19 * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm: 20 (WebCore::MediaRecorderPrivateWriter::create): 21 (WebCore::MediaRecorderPrivateWriter::initialize): 22 (WebCore::MediaRecorderPrivateWriter::setOptions): Deleted. 23 * platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h: 24 * platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm: 25 (WebCore::VideoSampleBufferCompressor::create): 26 (WebCore::VideoSampleBufferCompressor::VideoSampleBufferCompressor): 27 (WebCore::VideoSampleBufferCompressor::vtProfileLevel const): 28 (WebCore::VideoSampleBufferCompressor::initCompressionSession): 29 1 30 2021-05-27 Carlos Garcia Campos <cgarcia@igalia.com> 2 31 -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp
r267825 r278158 59 59 for (auto& item : mimeType.codecs()) { 60 60 auto codec = StringView(item).stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>); 61 // FIXME: We should further validate param ters.61 // FIXME: We should further validate parameters. 62 62 if (!startsWithLettersIgnoringASCIICase(codec, "avc1") && !startsWithLettersIgnoringASCIICase(codec, "mp4a")) 63 63 return false; -
trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h
r277958 r278158 86 86 void clear(); 87 87 88 bool initialize(); 89 void setOptions(const MediaRecorderPrivateOptions&); 88 bool initialize(const MediaRecorderPrivateOptions&); 90 89 91 90 static void compressedVideoOutputBufferCallback(void*, CMBufferQueueTriggerToken); -
trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm
r277934 r278158 99 99 { 100 100 auto writer = adoptRef(*new MediaRecorderPrivateWriter(hasAudio, hasVideo)); 101 if (!writer->initialize( ))101 if (!writer->initialize(options)) 102 102 return nullptr; 103 writer->setOptions(options);104 103 return writer; 105 104 } … … 132 131 } 133 132 134 bool MediaRecorderPrivateWriter::initialize( )133 bool MediaRecorderPrivateWriter::initialize(const MediaRecorderPrivateOptions& options) 135 134 { 136 135 NSError *error = nil; … … 150 149 if (!m_audioCompressor) 151 150 return false; 151 if (options.audioBitsPerSecond) 152 m_audioCompressor->setBitsPerSecond(*options.audioBitsPerSecond); 152 153 } 153 154 if (m_hasVideo) { 154 m_videoCompressor = VideoSampleBufferCompressor::create( kCMVideoCodecType_H264, compressedVideoOutputBufferCallback, this);155 m_videoCompressor = VideoSampleBufferCompressor::create(options.mimeType, compressedVideoOutputBufferCallback, this); 155 156 if (!m_videoCompressor) 156 157 return false; 157 } 158 if (options.videoBitsPerSecond) 159 m_videoCompressor->setBitsPerSecond(*options.videoBitsPerSecond); 160 } 161 158 162 return true; 159 }160 161 void MediaRecorderPrivateWriter::setOptions(const MediaRecorderPrivateOptions& options)162 {163 if (options.audioBitsPerSecond && m_audioCompressor)164 m_audioCompressor->setBitsPerSecond(*options.audioBitsPerSecond);165 if (options.videoBitsPerSecond && m_videoCompressor)166 m_videoCompressor->setBitsPerSecond(*options.videoBitsPerSecond);167 163 } 168 164 -
trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h
r274296 r278158 39 39 WTF_MAKE_FAST_ALLOCATED; 40 40 public: 41 static std::unique_ptr<VideoSampleBufferCompressor> create( CMVideoCodecType, CMBufferQueueTriggerCallback, void* callbackObject);41 static std::unique_ptr<VideoSampleBufferCompressor> create(String mimeType, CMBufferQueueTriggerCallback, void* callbackObject); 42 42 ~VideoSampleBufferCompressor(); 43 43 … … 51 51 52 52 private: 53 explicit VideoSampleBufferCompressor(CMVideoCodecType); 53 enum class Profile { Baseline, Main, High }; 54 VideoSampleBufferCompressor(CMVideoCodecType, Profile); 54 55 55 56 bool initialize(CMBufferQueueTriggerCallback, void* callbackObject); … … 57 58 void processSampleBuffer(CMSampleBufferRef); 58 59 bool initCompressionSession(CMVideoFormatDescriptionRef); 60 CFStringRef vtProfileLevel() const; 59 61 60 62 static void videoCompressionCallback(void *refCon, void*, OSStatus, VTEncodeInfoFlags, CMSampleBufferRef); … … 70 72 unsigned m_expectedFrameRate { 30 }; 71 73 Optional<unsigned> m_outputBitRate; 74 Profile m_profile; 72 75 }; 73 76 -
trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm
r274296 r278158 28 28 #if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION) 29 29 30 #import "ContentType.h" 30 31 #import "Logging.h" 31 32 #import <CoreMedia/CoreMedia.h> … … 40 41 using namespace PAL; 41 42 42 std::unique_ptr<VideoSampleBufferCompressor> VideoSampleBufferCompressor::create(CMVideoCodecType outputCodecType, CMBufferQueueTriggerCallback callback, void* callbackObject) 43 { 44 auto compressor = std::unique_ptr<VideoSampleBufferCompressor>(new VideoSampleBufferCompressor(outputCodecType)); 43 std::unique_ptr<VideoSampleBufferCompressor> VideoSampleBufferCompressor::create(String mimeType, CMBufferQueueTriggerCallback callback, void* callbackObject) 44 { 45 auto profile = Profile::Baseline; 46 for (auto codec : ContentType(mimeType).codecs()) { 47 if (startsWithLettersIgnoringASCIICase(codec, "avc1.") && codec.length() >= 11) { 48 if (codec[5] == '6' && codec[6] == '4') 49 profile = Profile::High; 50 else if (codec[5] == '4' && (codec[6] == 'd' || codec[6] == 'D')) 51 profile = Profile::Main; 52 break; 53 } 54 } 55 56 auto compressor = std::unique_ptr<VideoSampleBufferCompressor>(new VideoSampleBufferCompressor(kCMVideoCodecType_H264, profile)); 45 57 if (!compressor->initialize(callback, callbackObject)) 46 58 return nullptr; … … 48 60 } 49 61 50 VideoSampleBufferCompressor::VideoSampleBufferCompressor(CMVideoCodecType outputCodecType )62 VideoSampleBufferCompressor::VideoSampleBufferCompressor(CMVideoCodecType outputCodecType, Profile profile) 51 63 : m_serialDispatchQueue { WorkQueue::create("com.apple.VideoSampleBufferCompressor") } 52 64 , m_outputCodecType { outputCodecType } 65 , m_profile { profile } 53 66 { 54 67 } … … 112 125 OSStatus status = VTSessionSetProperty(vtSession, key, cfValue.get()); 113 126 return status; 127 } 128 129 CFStringRef VideoSampleBufferCompressor::vtProfileLevel() const 130 { 131 switch (m_profile) { 132 case Profile::Baseline: 133 return kVTProfileLevel_H264_Baseline_AutoLevel; 134 case Profile::High: 135 return kVTProfileLevel_H264_High_AutoLevel; 136 case Profile::Main: 137 return kVTProfileLevel_H264_Main_AutoLevel; 138 } 114 139 } 115 140 … … 138 163 RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_ExpectedFrameRate failed with %d", error); 139 164 165 error = VTSessionSetProperty(m_vtSession.get(), kVTCompressionPropertyKey_ProfileLevel, vtProfileLevel()); 166 if (error) { 167 RELEASE_LOG_ERROR(MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_ProfileLevel failed with %d for profile %d", error, m_profile); 168 if (m_profile != Profile::Baseline) { 169 error = VTSessionSetProperty(m_vtSession.get(), kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_Baseline_AutoLevel); 170 RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_ProfileLevel failed with %d for default profile", error); 171 } 172 } 173 140 174 if (m_outputBitRate) { 141 175 error = setCompressionSessionProperty(m_vtSession.get(), kVTCompressionPropertyKey_AverageBitRate, *m_outputBitRate);
Note: See TracChangeset
for help on using the changeset viewer.