Implement and test EncodedImageCallback in new ViE API.

R=mflodman@webrtc.org, pbos@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/4059004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5179 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
sprang@webrtc.org 2013-11-26 11:41:59 +00:00
parent c7ff8f990a
commit 4070935f4f
25 changed files with 337 additions and 14 deletions

View File

@ -18,6 +18,7 @@
#include "webrtc/call.h"
#include "webrtc/common_video/test/frame_generator.h"
#include "webrtc/frame_callback.h"
#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
@ -1040,4 +1041,77 @@ TEST_F(CallTest, PlaysOutAudioAndVideoInSync) {
VoiceEngine::Delete(voice_engine);
}
TEST_F(CallTest, ObserversEncodedFrames) {
class EncodedFrameTestObserver : public EncodedFrameObserver {
public:
EncodedFrameTestObserver() : length_(0),
frame_type_(kFrameEmpty),
called_(EventWrapper::Create()) {}
virtual ~EncodedFrameTestObserver() {}
virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
frame_type_ = encoded_frame.frame_type_;
length_ = encoded_frame.length_;
buffer_.reset(new uint8_t[length_]);
memcpy(buffer_.get(), encoded_frame.data_, length_);
called_->Set();
}
EventTypeWrapper Wait() {
return called_->Wait(kDefaultTimeoutMs);
}
void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
ASSERT_EQ(length_, observer.length_)
<< "Observed frames are of different lengths.";
EXPECT_EQ(frame_type_, observer.frame_type_)
<< "Observed frames have different frame types.";
EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
<< "Observed encoded frames have different content.";
}
private:
scoped_ptr<uint8_t[]> buffer_;
size_t length_;
FrameType frame_type_;
scoped_ptr<EventWrapper> called_;
};
EncodedFrameTestObserver post_encode_observer;
EncodedFrameTestObserver pre_decode_observer;
test::DirectTransport sender_transport, receiver_transport;
CreateCalls(Call::Config(&sender_transport),
Call::Config(&receiver_transport));
sender_transport.SetReceiver(receiver_call_->Receiver());
receiver_transport.SetReceiver(sender_call_->Receiver());
CreateTestConfigs();
send_config_.post_encode_callback = &post_encode_observer;
receive_config_.pre_decode_callback = &pre_decode_observer;
CreateStreams();
StartSending();
scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
send_config_.codec.width, send_config_.codec.height));
send_stream_->Input()->PutFrame(frame_generator->NextFrame(), 0);
EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
<< "Timed out while waiting for send-side encoded-frame callback.";
EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
<< "Timed out while waiting for pre-decode encoded-frame callback.";
post_encode_observer.ExpectEqualFrames(pre_decode_observer);
StopSending();
sender_transport.StopSending();
receiver_transport.StopSending();
DestroyStreams();
}
} // namespace webrtc

View File

@ -11,11 +11,22 @@
#ifndef WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_
#define WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_
#include "webrtc/common_types.h"
namespace webrtc {
class I420VideoFrame;
struct EncodedFrame;
struct EncodedFrame {
public:
EncodedFrame() : data_(NULL), length_(0), frame_type_(kFrameEmpty) {}
EncodedFrame(const uint8_t* data, size_t length, FrameType frame_type)
: data_(data), length_(length), frame_type_(frame_type) {}
const uint8_t* data_;
const size_t length_;
const FrameType frame_type_;
};
class I420FrameCallback {
public:
@ -34,6 +45,7 @@ class EncodedFrameObserver {
protected:
virtual ~EncodedFrameObserver() {}
};
} // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_

View File

@ -21,6 +21,7 @@ namespace webrtc
{
class Clock;
class EncodedImageCallback;
class VideoEncoder;
class VideoDecoder;
struct CodecSpecificInfo;
@ -600,6 +601,11 @@ public:
// Returns true if SuspendBelowMinBitrate is engaged and the video has been
// suspended due to bandwidth limitations; otherwise false.
virtual bool VideoSuspended() const = 0;
virtual void RegisterPreDecodeImageCallback(
EncodedImageCallback* observer) = 0;
virtual void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) = 0;
};
} // namespace webrtc

View File

@ -12,6 +12,7 @@
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/generic_encoder.h"
#include "webrtc/modules/video_coding/main/source/media_optimization.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
@ -147,7 +148,9 @@ _mediaOpt(NULL),
_encodedBytes(0),
_payloadType(0),
_codecType(kVideoCodecUnknown),
_internalSource(false)
_internalSource(false),
post_encode_callback_lock_(CriticalSectionWrapper::CreateCriticalSection()),
post_encode_callback_(NULL)
#ifdef DEBUG_ENCODER_BIT_STREAM
, _bitStreamAfterEncoder(NULL)
#endif
@ -177,6 +180,12 @@ VCMEncodedFrameCallback::Encoded(
const CodecSpecificInfo* codecSpecificInfo,
const RTPFragmentationHeader* fragmentationHeader)
{
{
CriticalSectionScoped cs(post_encode_callback_lock_.get());
if (post_encode_callback_) {
post_encode_callback_->Encoded(encodedImage);
}
}
FrameType frameType = VCMEncodedFrame::ConvertFrameType(encodedImage._frameType);
uint32_t encodedBytes = 0;
@ -271,4 +280,10 @@ void VCMEncodedFrameCallback::CopyCodecSpecific(const CodecSpecificInfo& info,
return;
}
}
void VCMEncodedFrameCallback::RegisterPostEncodeImageCallback(
EncodedImageCallback* callback) {
CriticalSectionScoped cs(post_encode_callback_lock_.get());
post_encode_callback_ = callback;
}
} // namespace webrtc

View File

@ -15,9 +15,13 @@
#include <stdio.h>
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc
{
class CriticalSectionWrapper;
namespace media_optimization {
class MediaOptimization;
} // namespace media_optimization
@ -55,6 +59,8 @@ public:
void SetCodecType(VideoCodecType codecType) {_codecType = codecType;};
void SetInternalSource(bool internalSource) { _internalSource = internalSource; };
void RegisterPostEncodeImageCallback(EncodedImageCallback* callback);
private:
/*
* Map information from info into rtp. If no relevant information is found
@ -69,6 +75,10 @@ private:
uint8_t _payloadType;
VideoCodecType _codecType;
bool _internalSource;
scoped_ptr<CriticalSectionWrapper> post_encode_callback_lock_;
EncodedImageCallback* post_encode_callback_;
#ifdef DEBUG_ENCODER_BIT_STREAM
FILE* _bitStreamAfterEncoder;
#endif

View File

@ -319,6 +319,16 @@ class VideoCodingModuleImpl : public VideoCodingModule {
return receiver_->SetReceiveChannelParameters(rtt);
}
virtual void RegisterPreDecodeImageCallback(
EncodedImageCallback* observer) OVERRIDE {
receiver_->RegisterPreDecodeImageCallback(observer);
}
virtual void RegisterPostEncodeImageCallback(
EncodedImageCallback* observer) OVERRIDE {
sender_->RegisterPostEncodeImageCallback(observer);
}
private:
scoped_ptr<vcm::VideoSender> sender_;
scoped_ptr<vcm::VideoReceiver> receiver_;

View File

@ -27,6 +27,9 @@
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc {
class EncodedFrameObserver;
namespace vcm {
class VCMProcessTimer {
@ -98,6 +101,9 @@ class VideoSender {
void SuspendBelowMinBitrate();
bool VideoSuspended() const;
void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback);
int32_t TimeUntilNextProcess();
int32_t Process();
@ -173,6 +179,8 @@ class VideoReceiver {
int32_t TimeUntilNextProcess();
int32_t Process();
void RegisterPreDecodeImageCallback(EncodedImageCallback* observer);
protected:
int32_t Decode(const webrtc::VCMEncodedFrame& frame);
int32_t RequestKeyFrame();
@ -213,6 +221,7 @@ class VideoReceiver {
VCMKeyRequestMode _keyRequestMode;
bool _scheduleKeyRequest;
size_t max_nack_list_size_;
EncodedImageCallback* pre_decode_image_callback_;
VCMCodecDataBase _codecDataBase;
VCMProcessTimer _receiveStatsTimer;

View File

@ -52,6 +52,7 @@ VideoReceiver::VideoReceiver(const int32_t id,
_keyRequestMode(kKeyOnError),
_scheduleKeyRequest(false),
max_nack_list_size_(0),
pre_decode_image_callback_(NULL),
_codecDataBase(id),
_receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_),
@ -400,6 +401,11 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
_timing.UpdateCurrentDelay(frame->RenderTimeMs(),
clock_->TimeInMilliseconds());
if (pre_decode_image_callback_) {
EncodedImage encoded_image(frame->EncodedImage());
pre_decode_image_callback_->Encoded(encoded_image);
}
#ifdef DEBUG_DECODER_BIT_STREAM
if (_bitStreamBeforeDecoder != NULL) {
// Write bit stream to file for debugging purposes
@ -815,5 +821,11 @@ int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
return _receiver.SetMinReceiverDelay(desired_delay_ms);
}
void VideoReceiver::RegisterPreDecodeImageCallback(
EncodedImageCallback* observer) {
CriticalSectionScoped cs(_receiveCritSect);
pre_decode_image_callback_ = observer;
}
} // namespace vcm
} // namespace webrtc

View File

@ -446,5 +446,11 @@ bool VideoSender::VideoSuspended() const {
return _mediaOpt.video_suspended();
}
void VideoSender::RegisterPostEncodeImageCallback(
EncodedImageCallback* observer) {
CriticalSectionScoped cs(_sendCritSect);
_encodedFrameCallback.RegisterPostEncodeImageCallback(observer);
}
} // namespace vcm
} // namespace webrtc

View File

@ -20,13 +20,16 @@ FakeEncoder::FakeEncoder(Clock* clock)
callback_(NULL),
target_bitrate_kbps_(0),
last_encode_time_ms_(0) {
memset(encoded_buffer_, 0, sizeof(encoded_buffer_));
// Generate some arbitrary not-all-zero data
for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
encoded_buffer_[i] = static_cast<uint8_t>(i);
}
}
FakeEncoder::~FakeEncoder() {}
void FakeEncoder::SetCodecSettings(VideoCodec* codec,
size_t num_streams) {
size_t num_streams) {
assert(num_streams > 0);
assert(num_streams <= kMaxSimulcastStreams);

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2013 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 "webrtc/video/encoded_frame_callback_adapter.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
namespace webrtc {
namespace internal {
EncodedFrameCallbackAdapter::EncodedFrameCallbackAdapter(
EncodedFrameObserver* observer) : observer_(observer) {
}
EncodedFrameCallbackAdapter::~EncodedFrameCallbackAdapter() {}
int32_t EncodedFrameCallbackAdapter::Encoded(
EncodedImage& encodedImage,
const CodecSpecificInfo* codecSpecificInfo,
const RTPFragmentationHeader* fragmentation) {
assert(observer_ != NULL);
FrameType frame_type =
VCMEncodedFrame::ConvertFrameType(encodedImage._frameType);
const EncodedFrame frame(encodedImage._buffer,
encodedImage._length,
frame_type);
observer_->EncodedFrameCallback(frame);
return 0;
}
} // namespace internal
} // namespace webrtc

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_VIDEO_ENCODED_FRAME_CALLBACK_ADAPTER_H_
#define WEBRTC_VIDEO_ENCODED_FRAME_CALLBACK_ADAPTER_H_
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/frame_callback.h"
namespace webrtc {
namespace internal {
class EncodedFrameCallbackAdapter : public EncodedImageCallback {
public:
explicit EncodedFrameCallbackAdapter(EncodedFrameObserver* observer);
virtual ~EncodedFrameCallbackAdapter();
virtual int32_t Encoded(EncodedImage& encodedImage,
const CodecSpecificInfo* codecSpecificInfo,
const RTPFragmentationHeader* fragmentation);
private:
EncodedFrameObserver* observer_;
};
} // namespace internal
} // namespace webrtc
#endif // WEBRTC_VIDEO_ENCODED_FRAME_CALLBACK_ADAPTER_H_

View File

@ -32,7 +32,10 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
const VideoReceiveStream::Config& config,
newapi::Transport* transport,
webrtc::VoiceEngine* voice_engine)
: transport_adapter_(transport), config_(config), channel_(-1) {
: transport_adapter_(transport),
encoded_frame_proxy_(config.pre_decode_callback),
config_(config),
channel_(-1) {
video_engine_base_ = ViEBase::GetInterface(video_engine);
// TODO(mflodman): Use the other CreateChannel method.
video_engine_base_->CreateChannel(channel_);
@ -96,6 +99,10 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
}
image_process_ = ViEImageProcess::GetInterface(video_engine);
if (config.pre_decode_callback) {
image_process_->RegisterPreDecodeImageCallback(channel_,
&encoded_frame_proxy_);
}
image_process_->RegisterPreRenderCallback(channel_,
config_.pre_render_callback);
@ -103,7 +110,8 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
}
VideoReceiveStream::~VideoReceiveStream() {
image_process_->DeRegisterPreEncodeCallback(channel_);
image_process_->DeRegisterPreRenderCallback(channel_);
image_process_->DeRegisterPreDecodeCallback(channel_);
render_->RemoveRenderer(channel_);
@ -161,6 +169,5 @@ int32_t VideoReceiveStream::RenderFrame(const uint32_t stream_id,
video_frame, video_frame.render_time_ms() - clock_->TimeInMilliseconds());
return 0;
}
} // internal
} // webrtc

View File

@ -16,6 +16,7 @@
#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/video/encoded_frame_callback_adapter.h"
#include "webrtc/video/transport_adapter.h"
#include "webrtc/video_engine/include/vie_render.h"
#include "webrtc/video_receive_stream.h"
@ -57,6 +58,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
private:
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
VideoReceiveStream::Config config_;
Clock* clock_;

View File

@ -83,6 +83,7 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
webrtc::VideoEngine* video_engine,
const VideoSendStream::Config& config)
: transport_adapter_(transport),
encoded_frame_proxy_(config.post_encode_callback),
codec_lock_(CriticalSectionWrapper::CreateCriticalSection()),
config_(config),
external_codec_(NULL) {
@ -199,6 +200,10 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport,
image_process_ = ViEImageProcess::GetInterface(video_engine);
image_process_->RegisterPreEncodeCallback(channel_,
config_.pre_encode_callback);
if (config_.post_encode_callback) {
image_process_->RegisterPostEncodeImageCallback(channel_,
&encoded_frame_proxy_);
}
if (config.suspend_below_min_bitrate) {
codec_->SuspendBelowMinBitrate(channel_);
@ -294,6 +299,5 @@ bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
return network_->ReceivedRTCPPacket(
channel_, packet, static_cast<int>(length)) == 0;
}
} // namespace internal
} // namespace webrtc

View File

@ -14,6 +14,7 @@
#include <vector>
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/video/encoded_frame_callback_adapter.h"
#include "webrtc/video/transport_adapter.h"
#include "webrtc/video_receive_stream.h"
#include "webrtc/video_send_stream.h"
@ -62,6 +63,7 @@ class VideoSendStream : public webrtc::VideoSendStream,
private:
TransportAdapter transport_adapter_;
EncodedFrameCallbackAdapter encoded_frame_proxy_;
scoped_ptr<CriticalSectionWrapper> codec_lock_;
VideoSendStream::Config config_;

View File

@ -11,6 +11,8 @@
'<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core',
],
'webrtc_video_sources': [
'video/encoded_frame_callback_adapter.cc',
'video/encoded_frame_callback_adapter.h',
'video/transport_adapter.cc',
'video/transport_adapter.h',
'video/video_receive_stream.cc',

View File

@ -18,12 +18,11 @@
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_IMAGE_PROCESS_H_
#include "webrtc/common_types.h"
#include "webrtc/common_video/interface/i420_video_frame.h"
namespace webrtc {
class EncodedImageCallback;
class I420FrameCallback;
class VideoEngine;
// This class declares an abstract interface for a user defined effect filter.
@ -98,6 +97,16 @@ class WEBRTC_DLLEXPORT ViEImageProcess {
I420FrameCallback* pre_encode_callback) = 0;
virtual void DeRegisterPreEncodeCallback(int video_channel) = 0;
virtual void RegisterPostEncodeImageCallback(
int video_channel,
EncodedImageCallback* post_encode_callback) = 0;
virtual void DeRegisterPostEncodeCallback(int video_channel) {}
virtual void RegisterPreDecodeImageCallback(
int video_channel,
EncodedImageCallback* pre_decode_callback) = 0;
virtual void DeRegisterPreDecodeCallback(int video_channel) {}
virtual void RegisterPreRenderCallback(
int video_channel,
I420FrameCallback* pre_render_callback) = 0;

View File

@ -1870,6 +1870,12 @@ void ViEChannel::RegisterPreRenderCallback(
pre_render_callback_ = pre_render_callback;
}
void ViEChannel::RegisterPreDecodeImageCallback(
EncodedImageCallback* pre_decode_callback) {
CriticalSectionScoped cs(callback_cs_.get());
vcm_.RegisterPreDecodeImageCallback(pre_decode_callback);
}
void ViEChannel::OnApplicationDataReceived(const int32_t id,
const uint8_t sub_type,
const uint32_t name,

View File

@ -33,6 +33,7 @@ class CallStatsObserver;
class ChannelStatsObserver;
class Config;
class CriticalSectionWrapper;
class EncodedImageCallback;
class Encryption;
class I420FrameCallback;
class PacedSender;
@ -320,8 +321,10 @@ class ViEChannel
int32_t RegisterEffectFilter(ViEEffectFilter* effect_filter);
// New-style callback, used by VideoReceiveStream.
// New-style callbacks, used by VideoReceiveStream.
void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
void RegisterPreDecodeImageCallback(
EncodedImageCallback* pre_decode_callback);
protected:
static bool ChannelDecodeThreadFunction(void* obj);

View File

@ -14,6 +14,7 @@
#include <algorithm>
#include "webrtc/common_video/interface/video_image.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
@ -21,6 +22,7 @@
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
@ -1183,6 +1185,15 @@ void ViEEncoder::DeRegisterPreEncodeCallback() {
pre_encode_callback_ = NULL;
}
void ViEEncoder::RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) {
vcm_.RegisterPostEncodeImageCallback(post_encode_callback);
}
void ViEEncoder::DeRegisterPostEncodeImageCallback() {
vcm_.RegisterPostEncodeImageCallback(NULL);
}
QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm)
: vpm_(vpm) {
}

View File

@ -29,6 +29,7 @@ namespace webrtc {
class Config;
class CriticalSectionWrapper;
class EncodedImageCallback;
class PacedSender;
class ProcessThread;
class QMVideoSettingsCallback;
@ -168,11 +169,15 @@ class ViEEncoder
// |threshold_bps| + |window_bps|.
virtual void SuspendBelowMinBitrate();
// New-style callback, used by VideoSendStream.
// New-style callbacks, used by VideoSendStream.
void RegisterPreEncodeCallback(I420FrameCallback* pre_encode_callback);
void DeRegisterPreEncodeCallback();
void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback);
void DeRegisterPostEncodeImageCallback();
int channel_id() const { return channel_id_; }
protected:
// Called by BitrateObserver.
void OnNetworkChanged(const uint32_t bitrate_bps,

View File

@ -284,6 +284,36 @@ void ViEImageProcessImpl::DeRegisterPreEncodeCallback(int video_channel) {
vie_encoder->DeRegisterPreEncodeCallback();
}
void ViEImageProcessImpl::RegisterPostEncodeImageCallback(
int video_channel,
EncodedImageCallback* post_encode_callback) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
assert(vie_encoder != NULL);
vie_encoder->RegisterPostEncodeImageCallback(post_encode_callback);
}
void ViEImageProcessImpl::DeRegisterPostEncodeCallback(int video_channel) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
assert(vie_encoder != NULL);
vie_encoder->DeRegisterPostEncodeImageCallback();
}
void ViEImageProcessImpl::RegisterPreDecodeImageCallback(
int video_channel,
EncodedImageCallback* pre_decode_callback) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* channel = cs.Channel(video_channel);
channel->RegisterPreDecodeImageCallback(pre_decode_callback);
}
void ViEImageProcessImpl::DeRegisterPreDecodeCallback(int video_channel) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* channel = cs.Channel(video_channel);
channel->RegisterPreDecodeImageCallback(NULL);
}
void ViEImageProcessImpl::RegisterPreRenderCallback(
int video_channel,
I420FrameCallback* pre_render_callback) {

View File

@ -43,6 +43,16 @@ class ViEImageProcessImpl
I420FrameCallback* pre_encode_callback) OVERRIDE;
virtual void DeRegisterPreEncodeCallback(int video_channel) OVERRIDE;
virtual void RegisterPostEncodeImageCallback(
int video_channel,
EncodedImageCallback* post_encode_callback) OVERRIDE;
virtual void DeRegisterPostEncodeCallback(int video_channel) OVERRIDE;
virtual void RegisterPreDecodeImageCallback(
int video_channel,
EncodedImageCallback* post_encode_callback) OVERRIDE;
virtual void DeRegisterPreDecodeCallback(int video_channel) OVERRIDE;
virtual void RegisterPreRenderCallback(
int video_channel,
I420FrameCallback* pre_render_callback) OVERRIDE;

View File

@ -71,7 +71,7 @@ class VideoSendStream {
struct Config {
Config()
: pre_encode_callback(NULL),
encoded_callback(NULL),
post_encode_callback(NULL),
local_renderer(NULL),
render_delay_ms(0),
encoder(NULL),
@ -113,7 +113,7 @@ class VideoSendStream {
// Called for each encoded frame, e.g. used for file storage. 'NULL'
// disables the callback.
EncodedFrameObserver* encoded_callback;
EncodedFrameObserver* post_encode_callback;
// Renderer for local preview. The local renderer will be called even if
// sending hasn't started. 'NULL' disables local rendering.