249 lines
8.1 KiB
C++
249 lines
8.1 KiB
C++
|
/*
|
||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#include "vie_renderer.h"
|
||
|
#include "video_render.h"
|
||
|
#include "video_render_defines.h"
|
||
|
#include "vie_render_manager.h"
|
||
|
#include "vplib.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
|
||
|
ViERenderer* ViERenderer::CreateViERenderer(
|
||
|
const WebRtc_Word32 renderId,
|
||
|
const WebRtc_Word32 engineId,
|
||
|
VideoRender& renderModule,
|
||
|
ViERenderManager& renderManager,
|
||
|
const WebRtc_UWord32 zOrder,
|
||
|
const float left,
|
||
|
const float top,
|
||
|
const float right,
|
||
|
const float bottom)
|
||
|
{
|
||
|
ViERenderer* self=new ViERenderer(renderId,engineId,renderModule,renderManager);
|
||
|
if(!self || self->Init(zOrder,left,top,right,bottom)!=0)
|
||
|
{
|
||
|
delete self;
|
||
|
self=NULL;
|
||
|
}
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
ViERenderer::~ViERenderer(void)
|
||
|
{
|
||
|
if(_ptrRenderCallback)
|
||
|
{
|
||
|
_renderModule.DeleteIncomingRenderStream( _renderId);
|
||
|
}
|
||
|
|
||
|
if(_ptrIncomingExternalCallback){
|
||
|
delete _ptrIncomingExternalCallback;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ViERenderer::ViERenderer(const WebRtc_Word32 renderId,const WebRtc_Word32 engineId,
|
||
|
VideoRender& renderModule,
|
||
|
ViERenderManager& renderManager)
|
||
|
:
|
||
|
_renderId(renderId),
|
||
|
_engineId(engineId),
|
||
|
_renderModule(renderModule),
|
||
|
_renderManager(renderManager),
|
||
|
_ptrRenderCallback(NULL),
|
||
|
_ptrIncomingExternalCallback(new ViEExternalRendererImpl())
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::Init(const WebRtc_UWord32 zOrder,
|
||
|
const float left,
|
||
|
const float top,
|
||
|
const float right,
|
||
|
const float bottom)
|
||
|
{
|
||
|
_ptrRenderCallback = (VideoRenderCallback*)_renderModule.AddIncomingRenderStream( _renderId, zOrder, left, top, right, bottom);
|
||
|
if (_ptrRenderCallback == NULL)
|
||
|
{
|
||
|
// Logging done
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::GetLastRenderedFrame(const WebRtc_Word32 renderID, webrtc::VideoFrame& videoFrame)
|
||
|
{
|
||
|
return _renderModule.GetLastRenderedFrame(renderID, videoFrame);
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::StartRender()
|
||
|
{
|
||
|
return _renderModule.StartRender(_renderId);
|
||
|
}
|
||
|
WebRtc_Word32 ViERenderer::StopRender()
|
||
|
{
|
||
|
return _renderModule.StopRender(_renderId);
|
||
|
}
|
||
|
|
||
|
// Implement ViEFrameCallback
|
||
|
void ViERenderer::DeliverFrame(int id,
|
||
|
webrtc::VideoFrame& videoFrame,
|
||
|
int numCSRCs,
|
||
|
const WebRtc_UWord32 CSRC[kRtpCsrcSize])
|
||
|
{
|
||
|
|
||
|
|
||
|
_ptrRenderCallback->RenderFrame(_renderId,videoFrame);
|
||
|
|
||
|
}
|
||
|
|
||
|
// Implement ViEFrameCallback
|
||
|
void ViERenderer::ProviderDestroyed(int id)
|
||
|
{
|
||
|
_renderManager.RemoveRenderStream(_renderId); // Remove the render stream since the provider is destroyed.
|
||
|
}
|
||
|
|
||
|
VideoRender& ViERenderer::RenderModule()
|
||
|
{
|
||
|
return _renderModule;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::ConfigureRenderer(const unsigned int zOrder,
|
||
|
const float left,
|
||
|
const float top,
|
||
|
const float right,
|
||
|
const float bottom)
|
||
|
{
|
||
|
return _renderModule.ConfigureRenderer(_renderId, zOrder, left, top, right, bottom);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::SetTimeoutImage(const webrtc::VideoFrame& timeoutImage,const WebRtc_Word32 timeoutValue)
|
||
|
{
|
||
|
return _renderModule.SetTimeoutImage(_renderId,timeoutImage,timeoutValue);
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::SetRenderStartImage(const webrtc::VideoFrame& startImage)
|
||
|
{
|
||
|
return _renderModule.SetStartImage(_renderId,startImage);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::EnableMirroring(const WebRtc_Word32 renderId, const bool enable, const bool mirrorXAxis, const bool mirrorYAxis)
|
||
|
{
|
||
|
return _renderModule.MirrorRenderStream(renderId, enable, mirrorXAxis, mirrorYAxis);
|
||
|
}
|
||
|
|
||
|
|
||
|
WebRtc_Word32 ViERenderer::SetExternalRenderer(const WebRtc_Word32 renderId, webrtc::RawVideoType videoInputFormat, ExternalRenderer* externalRenderer)
|
||
|
{
|
||
|
if(NULL == _ptrIncomingExternalCallback){
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
_ptrIncomingExternalCallback->SetViEExternalRenderer(externalRenderer, videoInputFormat);
|
||
|
return _renderModule.AddExternalRenderCallback(renderId, _ptrIncomingExternalCallback);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
ViEExternalRendererImpl::ViEExternalRendererImpl() :
|
||
|
_externalRenderer(NULL),
|
||
|
_externalRendererFormat(),
|
||
|
_externalRendererWidth(0),
|
||
|
_externalRendererHeight(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
int ViEExternalRendererImpl::SetViEExternalRenderer(ExternalRenderer* externalRenderer, webrtc::RawVideoType videoInputFormat)
|
||
|
{
|
||
|
_externalRenderer = externalRenderer;
|
||
|
_externalRendererFormat = videoInputFormat;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// implements VideoRenderCallback
|
||
|
WebRtc_Word32 ViEExternalRendererImpl::RenderFrame(const WebRtc_UWord32 streamId,
|
||
|
webrtc::VideoFrame& videoFrame)
|
||
|
{
|
||
|
webrtc::VideoFrame convertedFrame;
|
||
|
webrtc::VideoFrame* pConvertedFrame = &convertedFrame;
|
||
|
|
||
|
// convert to requested format
|
||
|
switch(_externalRendererFormat)
|
||
|
{
|
||
|
case webrtc::kVideoI420:
|
||
|
pConvertedFrame = &videoFrame;
|
||
|
break;
|
||
|
case webrtc::kVideoYV12:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kYV12,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToYV12(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
case webrtc::kVideoYUY2:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kYUY2,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToYUY2(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
case webrtc::kVideoUYVY:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kUYVY,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToUYVY(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
case webrtc::kVideoIYUV:
|
||
|
// no conversion available
|
||
|
break;
|
||
|
case webrtc::kVideoARGB:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kARGB,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToARGB(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
case webrtc::kVideoRGB24:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kRGB24,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToRGB24(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height());
|
||
|
break;
|
||
|
case webrtc::kVideoRGB565:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kRGB565,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToRGB565(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height());
|
||
|
break;
|
||
|
case webrtc::kVideoARGB4444:
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kARGB4444,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToARGB4444(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
case webrtc::kVideoARGB1555 :
|
||
|
convertedFrame.VerifyAndAllocate(webrtc::CalcBufferSize(webrtc::kARGB1555,videoFrame.Width(),videoFrame.Height()));
|
||
|
webrtc::ConvertI420ToARGB1555(videoFrame.Buffer(), convertedFrame.Buffer(), videoFrame.Width(), videoFrame.Height(), 0);
|
||
|
break;
|
||
|
default:
|
||
|
// the format is something funny. Should never reach here...
|
||
|
assert(false);
|
||
|
pConvertedFrame = NULL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(_externalRendererWidth!=videoFrame.Width() || _externalRendererHeight!=videoFrame.Height())
|
||
|
{
|
||
|
_externalRendererWidth = videoFrame.Width();
|
||
|
_externalRendererHeight = videoFrame.Height();
|
||
|
_externalRenderer->FrameSizeChange(_externalRendererWidth, _externalRendererHeight, streamId);
|
||
|
}
|
||
|
|
||
|
if(pConvertedFrame)
|
||
|
{
|
||
|
_externalRenderer->DeliverFrame(pConvertedFrame->Buffer(), pConvertedFrame->Length());
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
} //namespace webrtc
|
||
|
|
||
|
|
||
|
|
||
|
|