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/call.h"
#include "webrtc/common_video/test/frame_generator.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/remote_bitrate_estimator/include/rtp_to_ntp.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
@@ -1040,4 +1041,77 @@ TEST_F(CallTest, PlaysOutAudioAndVideoInSync) {
VoiceEngine::Delete(voice_engine); 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 } // namespace webrtc

View File

@@ -11,11 +11,22 @@
#ifndef WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_ #ifndef WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_
#define WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_ #define WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_
#include "webrtc/common_types.h"
namespace webrtc { namespace webrtc {
class I420VideoFrame; 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 { class I420FrameCallback {
public: public:
@@ -34,6 +45,7 @@ class EncodedFrameObserver {
protected: protected:
virtual ~EncodedFrameObserver() {} virtual ~EncodedFrameObserver() {}
}; };
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_ #endif // WEBRTC_VIDEO_ENGINE_NEW_INCLUDE_FRAME_CALLBACK_H_

View File

@@ -21,6 +21,7 @@ namespace webrtc
{ {
class Clock; class Clock;
class EncodedImageCallback;
class VideoEncoder; class VideoEncoder;
class VideoDecoder; class VideoDecoder;
struct CodecSpecificInfo; struct CodecSpecificInfo;
@@ -600,6 +601,11 @@ public:
// Returns true if SuspendBelowMinBitrate is engaged and the video has been // Returns true if SuspendBelowMinBitrate is engaged and the video has been
// suspended due to bandwidth limitations; otherwise false. // suspended due to bandwidth limitations; otherwise false.
virtual bool VideoSuspended() const = 0; virtual bool VideoSuspended() const = 0;
virtual void RegisterPreDecodeImageCallback(
EncodedImageCallback* observer) = 0;
virtual void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) = 0;
}; };
} // namespace webrtc } // 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/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/generic_encoder.h" #include "webrtc/modules/video_coding/main/source/generic_encoder.h"
#include "webrtc/modules/video_coding/main/source/media_optimization.h" #include "webrtc/modules/video_coding/main/source/media_optimization.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc { namespace webrtc {
@@ -147,7 +148,9 @@ _mediaOpt(NULL),
_encodedBytes(0), _encodedBytes(0),
_payloadType(0), _payloadType(0),
_codecType(kVideoCodecUnknown), _codecType(kVideoCodecUnknown),
_internalSource(false) _internalSource(false),
post_encode_callback_lock_(CriticalSectionWrapper::CreateCriticalSection()),
post_encode_callback_(NULL)
#ifdef DEBUG_ENCODER_BIT_STREAM #ifdef DEBUG_ENCODER_BIT_STREAM
, _bitStreamAfterEncoder(NULL) , _bitStreamAfterEncoder(NULL)
#endif #endif
@@ -177,6 +180,12 @@ VCMEncodedFrameCallback::Encoded(
const CodecSpecificInfo* codecSpecificInfo, const CodecSpecificInfo* codecSpecificInfo,
const RTPFragmentationHeader* fragmentationHeader) 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); FrameType frameType = VCMEncodedFrame::ConvertFrameType(encodedImage._frameType);
uint32_t encodedBytes = 0; uint32_t encodedBytes = 0;
@@ -271,4 +280,10 @@ void VCMEncodedFrameCallback::CopyCodecSpecific(const CodecSpecificInfo& info,
return; return;
} }
} }
void VCMEncodedFrameCallback::RegisterPostEncodeImageCallback(
EncodedImageCallback* callback) {
CriticalSectionScoped cs(post_encode_callback_lock_.get());
post_encode_callback_ = callback;
}
} // namespace webrtc } // namespace webrtc

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,7 +20,10 @@ FakeEncoder::FakeEncoder(Clock* clock)
callback_(NULL), callback_(NULL),
target_bitrate_kbps_(0), target_bitrate_kbps_(0),
last_encode_time_ms_(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() {} FakeEncoder::~FakeEncoder() {}

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,12 +18,11 @@
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_IMAGE_PROCESS_H_ #define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_IMAGE_PROCESS_H_
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/common_video/interface/i420_video_frame.h"
namespace webrtc { namespace webrtc {
class EncodedImageCallback;
class I420FrameCallback; class I420FrameCallback;
class VideoEngine; class VideoEngine;
// This class declares an abstract interface for a user defined effect filter. // 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; I420FrameCallback* pre_encode_callback) = 0;
virtual void DeRegisterPreEncodeCallback(int video_channel) = 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( virtual void RegisterPreRenderCallback(
int video_channel, int video_channel,
I420FrameCallback* pre_render_callback) = 0; I420FrameCallback* pre_render_callback) = 0;

View File

@@ -1870,6 +1870,12 @@ void ViEChannel::RegisterPreRenderCallback(
pre_render_callback_ = pre_render_callback; 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, void ViEChannel::OnApplicationDataReceived(const int32_t id,
const uint8_t sub_type, const uint8_t sub_type,
const uint32_t name, const uint32_t name,

View File

@@ -33,6 +33,7 @@ class CallStatsObserver;
class ChannelStatsObserver; class ChannelStatsObserver;
class Config; class Config;
class CriticalSectionWrapper; class CriticalSectionWrapper;
class EncodedImageCallback;
class Encryption; class Encryption;
class I420FrameCallback; class I420FrameCallback;
class PacedSender; class PacedSender;
@@ -320,8 +321,10 @@ class ViEChannel
int32_t RegisterEffectFilter(ViEEffectFilter* effect_filter); 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 RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
void RegisterPreDecodeImageCallback(
EncodedImageCallback* pre_decode_callback);
protected: protected:
static bool ChannelDecodeThreadFunction(void* obj); static bool ChannelDecodeThreadFunction(void* obj);

View File

@@ -14,6 +14,7 @@
#include <algorithm> #include <algorithm>
#include "webrtc/common_video/interface/video_image.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/pacing/include/paced_sender.h" #include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.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/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.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.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/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/tick_util.h" #include "webrtc/system_wrappers/interface/tick_util.h"
@@ -1183,6 +1185,15 @@ void ViEEncoder::DeRegisterPreEncodeCallback() {
pre_encode_callback_ = NULL; 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) QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm)
: vpm_(vpm) { : vpm_(vpm) {
} }

View File

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

View File

@@ -284,6 +284,36 @@ void ViEImageProcessImpl::DeRegisterPreEncodeCallback(int video_channel) {
vie_encoder->DeRegisterPreEncodeCallback(); 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( void ViEImageProcessImpl::RegisterPreRenderCallback(
int video_channel, int video_channel,
I420FrameCallback* pre_render_callback) { I420FrameCallback* pre_render_callback) {

View File

@@ -43,6 +43,16 @@ class ViEImageProcessImpl
I420FrameCallback* pre_encode_callback) OVERRIDE; I420FrameCallback* pre_encode_callback) OVERRIDE;
virtual void DeRegisterPreEncodeCallback(int video_channel) 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( virtual void RegisterPreRenderCallback(
int video_channel, int video_channel,
I420FrameCallback* pre_render_callback) OVERRIDE; I420FrameCallback* pre_render_callback) OVERRIDE;

View File

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