webrtc/video_engine/main/source/vie_renderer.cc

249 lines
8.1 KiB
C++
Raw Normal View History

/*
* 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