Deliver I420VideoFrames from VideoRender module.
Performance issue and simplicity, this implementation skips conversion to VideoEngine's frame format and then back again to I420VideoFrame. BUG=2526 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/3989004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5140 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
1ae1d0c471
commit
d29d4e9c08
@ -85,10 +85,10 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_ = webrtc::ViERender::GetInterface(video_engine);
|
render_ = ViERender::GetInterface(video_engine);
|
||||||
assert(render_ != NULL);
|
assert(render_ != NULL);
|
||||||
|
|
||||||
render_->AddRenderer(channel_, kVideoI420, this);
|
render_->AddRenderCallback(channel_, this);
|
||||||
|
|
||||||
if (voice_engine) {
|
if (voice_engine) {
|
||||||
video_engine_base_->SetVoiceEngine(voice_engine);
|
video_engine_base_->SetVoiceEngine(voice_engine);
|
||||||
@ -125,21 +125,17 @@ VideoReceiveStream::~VideoReceiveStream() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VideoReceiveStream::StartReceiving() {
|
void VideoReceiveStream::StartReceiving() {
|
||||||
if (render_->StartRender(channel_)) {
|
if (render_->StartRender(channel_) != 0)
|
||||||
abort();
|
abort();
|
||||||
}
|
if (video_engine_base_->StartReceive(channel_) != 0)
|
||||||
if (video_engine_base_->StartReceive(channel_) != 0) {
|
|
||||||
abort();
|
abort();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoReceiveStream::StopReceiving() {
|
void VideoReceiveStream::StopReceiving() {
|
||||||
if (render_->StopRender(channel_)) {
|
if (render_->StopRender(channel_) != 0)
|
||||||
abort();
|
abort();
|
||||||
}
|
if (video_engine_base_->StopReceive(channel_) != 0)
|
||||||
if (video_engine_base_->StopReceive(channel_) != 0) {
|
|
||||||
abort();
|
abort();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoReceiveStream::GetCurrentReceiveCodec(VideoCodec* receive_codec) {
|
void VideoReceiveStream::GetCurrentReceiveCodec(VideoCodec* receive_codec) {
|
||||||
@ -156,44 +152,15 @@ bool VideoReceiveStream::DeliverRtp(const uint8_t* packet, size_t length) {
|
|||||||
channel_, packet, static_cast<int>(length)) == 0;
|
channel_, packet, static_cast<int>(length)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoReceiveStream::FrameSizeChange(unsigned int width,
|
int32_t VideoReceiveStream::RenderFrame(const uint32_t stream_id,
|
||||||
unsigned int height,
|
I420VideoFrame& video_frame) {
|
||||||
unsigned int /*number_of_streams*/) {
|
if (config_.renderer == NULL)
|
||||||
width_ = width;
|
|
||||||
height_ = height;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int VideoReceiveStream::DeliverFrame(uint8_t* frame,
|
|
||||||
int buffer_size,
|
|
||||||
uint32_t timestamp,
|
|
||||||
int64_t render_time,
|
|
||||||
void* /*handle*/) {
|
|
||||||
if (config_.renderer == NULL) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
I420VideoFrame video_frame;
|
|
||||||
video_frame.CreateEmptyFrame(width_, height_, width_, height_, height_);
|
|
||||||
ConvertToI420(kI420,
|
|
||||||
frame,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width_,
|
|
||||||
height_,
|
|
||||||
buffer_size,
|
|
||||||
webrtc::kRotateNone,
|
|
||||||
&video_frame);
|
|
||||||
video_frame.set_timestamp(timestamp);
|
|
||||||
video_frame.set_render_time_ms(render_time);
|
|
||||||
|
|
||||||
config_.renderer->RenderFrame(video_frame,
|
|
||||||
render_time - clock_->TimeInMilliseconds());
|
|
||||||
|
|
||||||
|
config_.renderer->RenderFrame(
|
||||||
|
video_frame, video_frame.render_time_ms() - clock_->TimeInMilliseconds());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoReceiveStream::IsTextureSupported() { return false; }
|
|
||||||
|
|
||||||
} // internal
|
} // internal
|
||||||
} // webrtc
|
} // webrtc
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
|
#include "webrtc/modules/video_render/include/video_render_defines.h"
|
||||||
#include "webrtc/system_wrappers/interface/clock.h"
|
#include "webrtc/system_wrappers/interface/clock.h"
|
||||||
#include "webrtc/video/transport_adapter.h"
|
#include "webrtc/video/transport_adapter.h"
|
||||||
#include "webrtc/video_engine/include/vie_render.h"
|
#include "webrtc/video_engine/include/vie_render.h"
|
||||||
@ -34,7 +35,7 @@ class VoiceEngine;
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
||||||
public webrtc::ExternalRenderer {
|
public VideoRenderCallback {
|
||||||
public:
|
public:
|
||||||
VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
||||||
const VideoReceiveStream::Config& config,
|
const VideoReceiveStream::Config& config,
|
||||||
@ -47,12 +48,8 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
|||||||
|
|
||||||
virtual void GetCurrentReceiveCodec(VideoCodec* receive_codec) OVERRIDE;
|
virtual void GetCurrentReceiveCodec(VideoCodec* receive_codec) OVERRIDE;
|
||||||
|
|
||||||
virtual int FrameSizeChange(unsigned int width, unsigned int height,
|
virtual int32_t RenderFrame(const uint32_t stream_id,
|
||||||
unsigned int /*number_of_streams*/) OVERRIDE;
|
I420VideoFrame& video_frame) OVERRIDE;
|
||||||
virtual int DeliverFrame(uint8_t* frame, int buffer_size, uint32_t timestamp,
|
|
||||||
int64_t render_time, void* /*handle*/) OVERRIDE;
|
|
||||||
|
|
||||||
virtual bool IsTextureSupported() OVERRIDE;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool DeliverRtcp(const uint8_t* packet, size_t length);
|
virtual bool DeliverRtcp(const uint8_t* packet, size_t length);
|
||||||
@ -72,10 +69,6 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
|||||||
ViEImageProcess* image_process_;
|
ViEImageProcess* image_process_;
|
||||||
|
|
||||||
int channel_;
|
int channel_;
|
||||||
|
|
||||||
// TODO(pbos): Remove VideoReceiveStream can operate on I420 frames directly.
|
|
||||||
unsigned int height_;
|
|
||||||
unsigned int width_;
|
|
||||||
};
|
};
|
||||||
} // internal
|
} // internal
|
||||||
} // webrtc
|
} // webrtc
|
||||||
|
@ -22,6 +22,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
class VideoEngine;
|
class VideoEngine;
|
||||||
class VideoRender;
|
class VideoRender;
|
||||||
|
class VideoRenderCallback;
|
||||||
|
|
||||||
// This class declares an abstract interface to be used for external renderers.
|
// This class declares an abstract interface to be used for external renderers.
|
||||||
// The user implemented derived class is registered using AddRenderer().
|
// The user implemented derived class is registered using AddRenderer().
|
||||||
@ -111,6 +112,13 @@ class WEBRTC_DLLEXPORT ViERender {
|
|||||||
RawVideoType video_input_format,
|
RawVideoType video_input_format,
|
||||||
ExternalRenderer* renderer) = 0;
|
ExternalRenderer* renderer) = 0;
|
||||||
|
|
||||||
|
// Propagating VideoRenderCallback down to the VideoRender module for new API.
|
||||||
|
// Contains default-implementation not to break code mocking this interface.
|
||||||
|
// (Ugly, but temporary.)
|
||||||
|
virtual int AddRenderCallback(int render_id, VideoRenderCallback* callback) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ViERender() {}
|
ViERender() {}
|
||||||
virtual ~ViERender() {}
|
virtual ~ViERender() {}
|
||||||
|
@ -394,4 +394,35 @@ int ViERenderImpl::AddRenderer(const int render_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ViERenderImpl::AddRenderCallback(int render_id,
|
||||||
|
VideoRenderCallback* callback) {
|
||||||
|
if (render_id < kViEChannelIdBase || render_id > kViEChannelIdMax)
|
||||||
|
return -1;
|
||||||
|
// This is a channel.
|
||||||
|
ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
|
||||||
|
ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
|
||||||
|
if (!frame_provider) {
|
||||||
|
WEBRTC_TRACE(kTraceError,
|
||||||
|
kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id()),
|
||||||
|
"%s: FrameProvider id %d doesn't exist",
|
||||||
|
__FUNCTION__,
|
||||||
|
render_id);
|
||||||
|
shared_data_->SetLastError(kViERenderInvalidRenderId);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
|
||||||
|
render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
if (!renderer) {
|
||||||
|
shared_data_->SetLastError(kViERenderUnknownError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (renderer->SetVideoRenderCallback(render_id, callback) != 0) {
|
||||||
|
shared_data_->SetLastError(kViERenderUnknownError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame_provider->RegisterFrameCallback(render_id, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -46,6 +46,9 @@ class ViERenderImpl
|
|||||||
virtual int AddRenderer(const int render_id, RawVideoType video_input_format,
|
virtual int AddRenderer(const int render_id, RawVideoType video_input_format,
|
||||||
ExternalRenderer* renderer);
|
ExternalRenderer* renderer);
|
||||||
|
|
||||||
|
virtual int AddRenderCallback(int render_id,
|
||||||
|
VideoRenderCallback* callback) OVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ViERenderImpl(ViESharedData* shared_data);
|
explicit ViERenderImpl(ViESharedData* shared_data);
|
||||||
virtual ~ViERenderImpl();
|
virtual ~ViERenderImpl();
|
||||||
|
@ -104,6 +104,11 @@ int32_t ViERenderer::SetExternalRenderer(
|
|||||||
incoming_external_callback_);
|
incoming_external_callback_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t ViERenderer::SetVideoRenderCallback(int32_t render_id,
|
||||||
|
VideoRenderCallback* callback) {
|
||||||
|
return render_module_.AddExternalRenderCallback(render_id, callback);
|
||||||
|
}
|
||||||
|
|
||||||
ViERenderer::ViERenderer(const int32_t render_id,
|
ViERenderer::ViERenderer(const int32_t render_id,
|
||||||
const int32_t engine_id,
|
const int32_t engine_id,
|
||||||
VideoRender& render_module,
|
VideoRender& render_module,
|
||||||
|
@ -86,6 +86,9 @@ class ViERenderer: public ViEFrameCallback {
|
|||||||
RawVideoType video_input_format,
|
RawVideoType video_input_format,
|
||||||
ExternalRenderer* external_renderer);
|
ExternalRenderer* external_renderer);
|
||||||
|
|
||||||
|
int32_t SetVideoRenderCallback(const int32_t render_id,
|
||||||
|
VideoRenderCallback* callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ViERenderer(const int32_t render_id, const int32_t engine_id,
|
ViERenderer(const int32_t render_id, const int32_t engine_id,
|
||||||
VideoRender& render_module,
|
VideoRender& render_module,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user