Added API to set expected render delay.
BUG=905 TEST=API test added and manual delay tests. Review URL: https://webrtc-codereview.appspot.com/810005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2841 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
a30eb31729
commit
f4f2145c6e
@ -236,6 +236,13 @@ public:
|
|||||||
/*
|
/*
|
||||||
* re-configure renderer
|
* re-configure renderer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Set the expected time needed by the graphics card or external renderer,
|
||||||
|
// i.e. frames will be released for rendering |delay_ms| before set render
|
||||||
|
// time in the video frame.
|
||||||
|
virtual WebRtc_Word32 SetExpectedRenderDelay(WebRtc_UWord32 stream_id,
|
||||||
|
WebRtc_Word32 delay_ms) = 0;
|
||||||
|
|
||||||
virtual WebRtc_Word32 ConfigureRenderer(const WebRtc_UWord32 streamId,
|
virtual WebRtc_Word32 ConfigureRenderer(const WebRtc_UWord32 streamId,
|
||||||
const unsigned int zOrder,
|
const unsigned int zOrder,
|
||||||
const float left, const float top,
|
const float left, const float top,
|
||||||
|
@ -175,6 +175,18 @@ WebRtc_Word32 IncomingVideoStream::EnableMirroring(const bool enable,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 IncomingVideoStream::SetExpectedRenderDelay(
|
||||||
|
WebRtc_Word32 delay_ms) {
|
||||||
|
CriticalSectionScoped csS(&stream_critsect_);
|
||||||
|
if (running_) {
|
||||||
|
WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, module_id_,
|
||||||
|
"%s(%d) for stream %d", __FUNCTION__, delay_ms, stream_id_);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CriticalSectionScoped cs(buffer_critsect_);
|
||||||
|
return render_buffers_.SetRenderDelay(delay_ms);
|
||||||
|
}
|
||||||
|
|
||||||
WebRtc_Word32 IncomingVideoStream::SetExternalCallback(
|
WebRtc_Word32 IncomingVideoStream::SetExternalCallback(
|
||||||
VideoRenderCallback* external_callback) {
|
VideoRenderCallback* external_callback) {
|
||||||
CriticalSectionScoped cs(&stream_critsect_);
|
CriticalSectionScoped cs(&stream_critsect_);
|
||||||
|
@ -68,6 +68,8 @@ class IncomingVideoStream : public VideoRenderCallback {
|
|||||||
const bool mirror_xaxis,
|
const bool mirror_xaxis,
|
||||||
const bool mirror_yaxis);
|
const bool mirror_yaxis);
|
||||||
|
|
||||||
|
WebRtc_Word32 SetExpectedRenderDelay(WebRtc_Word32 delay_ms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bool IncomingVideoStreamThreadFun(void* obj);
|
static bool IncomingVideoStreamThreadFun(void* obj);
|
||||||
bool IncomingVideoStreamProcess();
|
bool IncomingVideoStreamProcess();
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
WebRtc_Word32 KEventMaxWaitTimeMs = 200;
|
const WebRtc_Word32 KEventMaxWaitTimeMs = 200;
|
||||||
|
const WebRtc_Word32 kMinRenderDelayMs = 10;
|
||||||
|
const WebRtc_Word32 kMaxRenderDelayMs= 500;
|
||||||
|
|
||||||
VideoRenderFrames::VideoRenderFrames()
|
VideoRenderFrames::VideoRenderFrames()
|
||||||
: incoming_frames_(),
|
: incoming_frames_(),
|
||||||
@ -167,6 +169,14 @@ WebRtc_UWord32 VideoRenderFrames::TimeToNextFrameRelease() {
|
|||||||
|
|
||||||
WebRtc_Word32 VideoRenderFrames::SetRenderDelay(
|
WebRtc_Word32 VideoRenderFrames::SetRenderDelay(
|
||||||
const WebRtc_UWord32 render_delay) {
|
const WebRtc_UWord32 render_delay) {
|
||||||
|
if (render_delay < kMinRenderDelayMs ||
|
||||||
|
render_delay > kMaxRenderDelayMs) {
|
||||||
|
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer,
|
||||||
|
-1, "%s(%d): Invalid argument.", __FUNCTION__,
|
||||||
|
render_delay);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
render_delay_ms_ = render_delay;
|
render_delay_ms_ = render_delay;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -845,6 +845,37 @@ WebRtc_Word32 ModuleVideoRenderImpl::GetLastRenderedFrame(
|
|||||||
return incomingStream->GetLastRenderedFrame(frame);
|
return incomingStream->GetLastRenderedFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 ModuleVideoRenderImpl::SetExpectedRenderDelay(
|
||||||
|
WebRtc_UWord32 stream_id, WebRtc_Word32 delay_ms) {
|
||||||
|
CriticalSectionScoped cs(_moduleCrit);
|
||||||
|
|
||||||
|
if (!_ptrRenderer) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
|
||||||
|
"%s: No renderer", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapItem *item = _streamRenderMap.Find(stream_id);
|
||||||
|
if (item == NULL) {
|
||||||
|
// This stream doesn't exist
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
|
||||||
|
"%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
|
||||||
|
delay_ms);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncomingVideoStream* incoming_stream =
|
||||||
|
static_cast<IncomingVideoStream*> (item->GetItem());
|
||||||
|
if (incoming_stream == NULL) {
|
||||||
|
// This should never happen
|
||||||
|
assert(false);
|
||||||
|
_streamRenderMap.Erase(item);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return incoming_stream->SetExpectedRenderDelay(delay_ms);
|
||||||
|
}
|
||||||
|
|
||||||
WebRtc_Word32 ModuleVideoRenderImpl::ConfigureRenderer(
|
WebRtc_Word32 ModuleVideoRenderImpl::ConfigureRenderer(
|
||||||
const WebRtc_UWord32 streamId,
|
const WebRtc_UWord32 streamId,
|
||||||
const unsigned int zOrder,
|
const unsigned int zOrder,
|
||||||
|
@ -119,6 +119,9 @@ public:
|
|||||||
virtual WebRtc_Word32 GetLastRenderedFrame(const WebRtc_UWord32 streamId,
|
virtual WebRtc_Word32 GetLastRenderedFrame(const WebRtc_UWord32 streamId,
|
||||||
VideoFrame &frame) const;
|
VideoFrame &frame) const;
|
||||||
|
|
||||||
|
virtual WebRtc_Word32 SetExpectedRenderDelay(WebRtc_UWord32 stream_id,
|
||||||
|
WebRtc_Word32 delay_ms);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Start/Stop
|
* Start/Stop
|
||||||
|
@ -81,6 +81,11 @@ class WEBRTC_DLLEXPORT ViERender {
|
|||||||
// Stops rendering a render stream.
|
// Stops rendering a render stream.
|
||||||
virtual int StopRender(const int render_id) = 0;
|
virtual int StopRender(const int render_id) = 0;
|
||||||
|
|
||||||
|
// Set expected render time needed by graphics card or external renderer, i.e.
|
||||||
|
// the number of ms a frame will be sent to rendering before the actual render
|
||||||
|
// time.
|
||||||
|
virtual int SetExpectedRenderDelay(int render_id, int render_delay) = 0;
|
||||||
|
|
||||||
// Configures an already added render stream.
|
// Configures an already added render stream.
|
||||||
virtual int ConfigureRender(int render_id,
|
virtual int ConfigureRender(int render_id,
|
||||||
const unsigned int z_order,
|
const unsigned int z_order,
|
||||||
|
@ -289,7 +289,31 @@ void ViEAutoTest::ViERenderExtendedTest()
|
|||||||
tbCapture.Disconnect(tbChannel.videoChannel);
|
tbCapture.Disconnect(tbChannel.videoChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViEAutoTest::ViERenderAPITest()
|
void ViEAutoTest::ViERenderAPITest() {
|
||||||
{
|
TbInterfaces ViE("ViERenderAPITest");
|
||||||
// TODO(unknown): add the real tests cases
|
|
||||||
|
TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
|
||||||
|
TbCaptureDevice tbCapture(ViE);
|
||||||
|
tbCapture.ConnectTo(tbChannel.videoChannel);
|
||||||
|
tbChannel.StartReceive();
|
||||||
|
tbChannel.StartSend();
|
||||||
|
|
||||||
|
EXPECT_EQ(0, ViE.render->AddRenderer(
|
||||||
|
tbCapture.captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
|
||||||
|
EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
|
||||||
|
EXPECT_EQ(0, ViE.render->AddRenderer(
|
||||||
|
tbChannel.videoChannel, _window2, 1, 0.0, 0.0, 1.0, 1.0));
|
||||||
|
EXPECT_EQ(0, ViE.render->StartRender(tbChannel.videoChannel));
|
||||||
|
|
||||||
|
// Test setting HW render delay.
|
||||||
|
// Already started.
|
||||||
|
EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 50));
|
||||||
|
EXPECT_EQ(0, ViE.render->StopRender(tbChannel.videoChannel));
|
||||||
|
// Invalid values.
|
||||||
|
EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 9));
|
||||||
|
EXPECT_EQ(-1, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel,
|
||||||
|
501));
|
||||||
|
// Valid values.
|
||||||
|
EXPECT_EQ(0, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 11));
|
||||||
|
EXPECT_EQ(0, ViE.render->SetExpectedRenderDelay(tbChannel.videoChannel, 499));
|
||||||
}
|
}
|
||||||
|
@ -262,6 +262,27 @@ int ViERenderImpl::StopRender(const int render_id) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ViERenderImpl::SetExpectedRenderDelay(int render_id, int render_delay) {
|
||||||
|
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id(), render_id),
|
||||||
|
"%s(channel: %d)", __FUNCTION__, render_id);
|
||||||
|
ViERenderManagerScoped rs(*(shared_data_->render_manager()));
|
||||||
|
ViERenderer* renderer = rs.Renderer(render_id);
|
||||||
|
if (!renderer) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id(), render_id),
|
||||||
|
"%s: No renderer with render_id %d exist.", __FUNCTION__,
|
||||||
|
render_id);
|
||||||
|
shared_data_->SetLastError(kViERenderInvalidRenderId);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (renderer->SetExpectedRenderDelay(render_delay) != 0) {
|
||||||
|
shared_data_->SetLastError(kViERenderUnknownError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ViERenderImpl::ConfigureRender(int render_id, const unsigned int z_order,
|
int ViERenderImpl::ConfigureRender(int render_id, const unsigned int z_order,
|
||||||
const float left, const float top,
|
const float left, const float top,
|
||||||
const float right, const float bottom) {
|
const float right, const float bottom) {
|
||||||
|
@ -36,6 +36,7 @@ class ViERenderImpl
|
|||||||
virtual int RemoveRenderer(const int render_id);
|
virtual int RemoveRenderer(const int render_id);
|
||||||
virtual int StartRender(const int render_id);
|
virtual int StartRender(const int render_id);
|
||||||
virtual int StopRender(const int render_id);
|
virtual int StopRender(const int render_id);
|
||||||
|
virtual int SetExpectedRenderDelay(int render_id, int render_delay);
|
||||||
virtual int ConfigureRender(int render_id, const unsigned int z_order,
|
virtual int ConfigureRender(int render_id, const unsigned int z_order,
|
||||||
const float left, const float top,
|
const float left, const float top,
|
||||||
const float right, const float bottom);
|
const float right, const float bottom);
|
||||||
|
@ -55,6 +55,10 @@ WebRtc_Word32 ViERenderer::GetLastRenderedFrame(const WebRtc_Word32 renderID,
|
|||||||
return render_module_.GetLastRenderedFrame(renderID, video_frame);
|
return render_module_.GetLastRenderedFrame(renderID, video_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ViERenderer::SetExpectedRenderDelay(int render_delay) {
|
||||||
|
return render_module_.SetExpectedRenderDelay(render_id_, render_delay);
|
||||||
|
}
|
||||||
|
|
||||||
WebRtc_Word32 ViERenderer::ConfigureRenderer(const unsigned int z_order,
|
WebRtc_Word32 ViERenderer::ConfigureRenderer(const unsigned int z_order,
|
||||||
const float left,
|
const float left,
|
||||||
const float top,
|
const float top,
|
||||||
|
@ -62,6 +62,8 @@ class ViERenderer: public ViEFrameCallback {
|
|||||||
WebRtc_Word32 GetLastRenderedFrame(const WebRtc_Word32 renderID,
|
WebRtc_Word32 GetLastRenderedFrame(const WebRtc_Word32 renderID,
|
||||||
VideoFrame& video_frame);
|
VideoFrame& video_frame);
|
||||||
|
|
||||||
|
int SetExpectedRenderDelay(int render_delay);
|
||||||
|
|
||||||
WebRtc_Word32 ConfigureRenderer(const unsigned int z_order,
|
WebRtc_Word32 ConfigureRenderer(const unsigned int z_order,
|
||||||
const float left,
|
const float left,
|
||||||
const float top,
|
const float top,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user