| /* |
| * Copyright (C) 2018 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| |
| #include "config.h" |
| #include "MediaRecorderPrivateAVFImpl.h" |
| |
| #if ENABLE(MEDIA_STREAM) |
| |
| #include "AudioStreamDescription.h" |
| #include "MediaSample.h" |
| #include "MediaStreamPrivate.h" |
| #include "SharedBuffer.h" |
| #include "WebAudioBufferList.h" |
| |
| namespace WebCore { |
| |
| std::unique_ptr<MediaRecorderPrivateAVFImpl> MediaRecorderPrivateAVFImpl::create(const MediaStreamPrivate& stream) |
| { |
| // FIXME: we will need to implement support for multiple audio/video tracks |
| // Currently we only choose the first track as the recorded track. |
| // FIXME: We would better to throw an exception to JavaScript if writer creation fails. |
| |
| String audioTrackId; |
| String videoTrackId; |
| const MediaStreamTrackPrivate* audioTrack { nullptr }; |
| const MediaStreamTrackPrivate* videoTrack { nullptr }; |
| for (auto& track : stream.tracks()) { |
| if (!track->enabled() || track->ended()) |
| continue; |
| switch (track->type()) { |
| case RealtimeMediaSource::Type::Video: { |
| auto& settings = track->settings(); |
| if (!videoTrack && settings.supportsWidth() && settings.supportsHeight()) { |
| videoTrack = track.get(); |
| videoTrackId = videoTrack->id(); |
| } |
| break; |
| } |
| case RealtimeMediaSource::Type::Audio: |
| if (!audioTrack) { |
| audioTrack = track.get(); |
| audioTrackId = audioTrack->id(); |
| } |
| break; |
| case RealtimeMediaSource::Type::None: |
| break; |
| } |
| } |
| auto writer = MediaRecorderPrivateWriter::create(audioTrack, videoTrack); |
| if (!writer) |
| return nullptr; |
| |
| return makeUnique<MediaRecorderPrivateAVFImpl>(writer.releaseNonNull(), WTFMove(audioTrackId), WTFMove(videoTrackId)); |
| } |
| |
| MediaRecorderPrivateAVFImpl::MediaRecorderPrivateAVFImpl(Ref<MediaRecorderPrivateWriter>&& writer, String&& audioTrackId, String&& videoTrackId) |
| : m_writer(WTFMove(writer)) |
| , m_recordedAudioTrackID(WTFMove(audioTrackId)) |
| , m_recordedVideoTrackID(WTFMove(videoTrackId)) |
| { |
| } |
| |
| void MediaRecorderPrivateAVFImpl::sampleBufferUpdated(MediaStreamTrackPrivate& track, MediaSample& sampleBuffer) |
| { |
| if (track.id() != m_recordedVideoTrackID) |
| return; |
| m_writer->appendVideoSampleBuffer(sampleBuffer.platformSample().sample.cmSampleBuffer); |
| } |
| |
| void MediaRecorderPrivateAVFImpl::audioSamplesAvailable(MediaStreamTrackPrivate& track, const WTF::MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount) |
| { |
| if (track.id() != m_recordedAudioTrackID) |
| return; |
| ASSERT(is<WebAudioBufferList>(data)); |
| ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType); |
| m_writer->appendAudioSampleBuffer(data, description, mediaTime, sampleCount); |
| } |
| |
| void MediaRecorderPrivateAVFImpl::stopRecording() |
| { |
| m_writer->stopRecording(); |
| } |
| |
| RefPtr<SharedBuffer> MediaRecorderPrivateAVFImpl::fetchData() |
| { |
| return m_writer->fetchData(); |
| } |
| |
| const String& MediaRecorderPrivateAVFImpl::mimeType() |
| { |
| static NeverDestroyed<const String> mp4MimeType(MAKE_STATIC_STRING_IMPL("video/mp4")); |
| // FIXME: we will need to support more MIME types. |
| return mp4MimeType; |
| } |
| |
| } // namespace WebCore |
| |
| #endif // ENABLE(MEDIA_STREAM) |