blob: 7d86f640a8c418ba1024cc374171c482f6f9f9b9 [file] [log] [blame]
/*
* Copyright (C) 2017 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions
* are required to be 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. AND 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 "RealtimeOutgoingVideoSourceCocoa.h"
#if USE(LIBWEBRTC)
#include "CVUtilities.h"
#include "ImageRotationSessionVT.h"
#include "Logging.h"
#include "RealtimeIncomingVideoSourceCocoa.h"
#include "RealtimeVideoUtilities.h"
#include "VideoFrameLibWebRTC.h"
ALLOW_UNUSED_PARAMETERS_BEGIN
#include <webrtc/api/video/i420_buffer.h>
#include <webrtc/common_video/libyuv/include/webrtc_libyuv.h>
#include <webrtc/sdk/WebKit/WebKitUtilities.h>
ALLOW_UNUSED_PARAMETERS_END
#include <pal/cf/CoreMediaSoftLink.h>
#include "CoreVideoSoftLink.h"
namespace WebCore {
Ref<RealtimeOutgoingVideoSource> RealtimeOutgoingVideoSource::create(Ref<MediaStreamTrackPrivate>&& videoSource)
{
return RealtimeOutgoingVideoSourceCocoa::create(WTFMove(videoSource));
}
Ref<RealtimeOutgoingVideoSourceCocoa> RealtimeOutgoingVideoSourceCocoa::create(Ref<MediaStreamTrackPrivate>&& videoSource)
{
return adoptRef(*new RealtimeOutgoingVideoSourceCocoa(WTFMove(videoSource)));
}
RealtimeOutgoingVideoSourceCocoa::RealtimeOutgoingVideoSourceCocoa(Ref<MediaStreamTrackPrivate>&& videoSource)
: RealtimeOutgoingVideoSource(WTFMove(videoSource))
{
}
void RealtimeOutgoingVideoSourceCocoa::videoFrameAvailable(VideoFrame& videoFrame, VideoFrameTimeMetadata)
{
#if !RELEASE_LOG_DISABLED
if (!(++m_numberOfFrames % 60))
ALWAYS_LOG(LOGIDENTIFIER, "frame ", m_numberOfFrames);
#endif
switch (videoFrame.rotation()) {
case VideoFrame::Rotation::None:
m_currentRotation = webrtc::kVideoRotation_0;
break;
case VideoFrame::Rotation::UpsideDown:
m_currentRotation = webrtc::kVideoRotation_180;
break;
case VideoFrame::Rotation::Right:
m_currentRotation = webrtc::kVideoRotation_90;
break;
case VideoFrame::Rotation::Left:
m_currentRotation = webrtc::kVideoRotation_270;
break;
}
bool shouldApplyRotation = m_shouldApplyRotation && m_currentRotation != webrtc::kVideoRotation_0;
if (!shouldApplyRotation) {
if (videoFrame.isRemoteProxy()) {
Ref remoteVideoFrame { videoFrame };
auto size = videoFrame.presentationSize();
sendFrame(webrtc::toWebRTCVideoFrameBuffer(&remoteVideoFrame.leakRef(),
[](auto* pointer) { return static_cast<VideoFrame*>(pointer)->pixelBuffer(); },
[](auto* pointer) { static_cast<VideoFrame*>(pointer)->deref(); },
static_cast<int>(size.width()), static_cast<int>(size.height())));
return;
}
if (videoFrame.isLibWebRTC()) {
sendFrame(downcast<VideoFrameLibWebRTC>(videoFrame).buffer());
return;
}
}
#if ASSERT_ENABLED
auto pixelFormat = videoFrame.pixelFormat();
// FIXME: We should use a pixel conformer for other pixel formats and kCVPixelFormatType_32BGRA.
ASSERT(pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange || pixelFormat == kCVPixelFormatType_32BGRA);
#endif
RetainPtr<CVPixelBufferRef> convertedBuffer = videoFrame.pixelBuffer();
if (shouldApplyRotation)
convertedBuffer = rotatePixelBuffer(convertedBuffer.get(), m_currentRotation);
sendFrame(webrtc::pixelBufferToFrame(convertedBuffer.get()));
}
rtc::scoped_refptr<webrtc::VideoFrameBuffer> RealtimeOutgoingVideoSourceCocoa::createBlackFrame(size_t width, size_t height)
{
return webrtc::pixelBufferToFrame(createBlackPixelBuffer(width, height).get());
}
} // namespace WebCore
#endif // USE(LIBWEBRTC)