aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--webrtc/call_tests.cc74
-rw-r--r--webrtc/frame_callback.h14
-rw-r--r--webrtc/modules/video_coding/main/interface/video_coding.h6
-rw-r--r--webrtc/modules/video_coding/main/source/generic_encoder.cc17
-rw-r--r--webrtc/modules/video_coding/main/source/generic_encoder.h10
-rw-r--r--webrtc/modules/video_coding/main/source/video_coding_impl.cc10
-rw-r--r--webrtc/modules/video_coding/main/source/video_coding_impl.h9
-rw-r--r--webrtc/modules/video_coding/main/source/video_receiver.cc12
-rw-r--r--webrtc/modules/video_coding/main/source/video_sender.cc6
-rw-r--r--webrtc/test/fake_encoder.cc7
-rw-r--r--webrtc/video/encoded_frame_callback_adapter.cc39
-rw-r--r--webrtc/video/encoded_frame_callback_adapter.h36
-rw-r--r--webrtc/video/video_receive_stream.cc13
-rw-r--r--webrtc/video/video_receive_stream.h2
-rw-r--r--webrtc/video/video_send_stream.cc6
-rw-r--r--webrtc/video/video_send_stream.h2
-rw-r--r--webrtc/video/webrtc_video.gypi2
-rw-r--r--webrtc/video_engine/include/vie_image_process.h13
-rw-r--r--webrtc/video_engine/vie_channel.cc6
-rw-r--r--webrtc/video_engine/vie_channel.h5
-rw-r--r--webrtc/video_engine/vie_encoder.cc11
-rw-r--r--webrtc/video_engine/vie_encoder.h7
-rw-r--r--webrtc/video_engine/vie_image_process_impl.cc30
-rw-r--r--webrtc/video_engine/vie_image_process_impl.h10
-rw-r--r--webrtc/video_send_stream.h4
25 files changed, 337 insertions, 14 deletions
diff --git a/webrtc/call_tests.cc b/webrtc/call_tests.cc
index 773886d77e..539328617e 100644
--- a/webrtc/call_tests.cc
+++ b/webrtc/call_tests.cc
@@ -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
diff --git a/webrtc/frame_callback.h b/webrtc/frame_callback.h
index 7f542450ab..cfb07d8b16 100644
--- a/webrtc/frame_callback.h
+++ b/webrtc/frame_callback.h
@@ -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_
diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h
index 9fb98c3653..c0166761e8 100644
--- a/webrtc/modules/video_coding/main/interface/video_coding.h
+++ b/webrtc/modules/video_coding/main/interface/video_coding.h
@@ -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
diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.cc b/webrtc/modules/video_coding/main/source/generic_encoder.cc
index c6ab9fbfbf..064470b166 100644
--- a/webrtc/modules/video_coding/main/source/generic_encoder.cc
+++ b/webrtc/modules/video_coding/main/source/generic_encoder.cc
@@ -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
diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.h b/webrtc/modules/video_coding/main/source/generic_encoder.h
index 0c2d287a9d..c5cfeabc26 100644
--- a/webrtc/modules/video_coding/main/source/generic_encoder.h
+++ b/webrtc/modules/video_coding/main/source/generic_encoder.h
@@ -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
diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc
index 8282edc44f..1decc2f112 100644
--- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc
+++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc
@@ -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_;
diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h
index c1d02d94e9..d9564c04bd 100644
--- a/webrtc/modules/video_coding/main/source/video_coding_impl.h
+++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h
@@ -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;
diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc
index cea8b448d5..68668eae7d 100644
--- a/webrtc/modules/video_coding/main/source/video_receiver.cc
+++ b/webrtc/modules/video_coding/main/source/video_receiver.cc
@@ -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
diff --git a/webrtc/modules/video_coding/main/source/video_sender.cc b/webrtc/modules/video_coding/main/source/video_sender.cc
index 5a9a56303f..948218b83a 100644
--- a/webrtc/modules/video_coding/main/source/video_sender.cc
+++ b/webrtc/modules/video_coding/main/source/video_sender.cc
@@ -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
diff --git a/webrtc/test/fake_encoder.cc b/webrtc/test/fake_encoder.cc
index eec75bef5b..f4e5227ed6 100644
--- a/webrtc/test/fake_encoder.cc
+++ b/webrtc/test/fake_encoder.cc
@@ -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);
diff --git a/webrtc/video/encoded_frame_callback_adapter.cc b/webrtc/video/encoded_frame_callback_adapter.cc
new file mode 100644
index 0000000000..f5eca7ce44
--- /dev/null
+++ b/webrtc/video/encoded_frame_callback_adapter.cc
@@ -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
diff --git a/webrtc/video/encoded_frame_callback_adapter.h b/webrtc/video/encoded_frame_callback_adapter.h
new file mode 100644
index 0000000000..d3814797ad
--- /dev/null
+++ b/webrtc/video/encoded_frame_callback_adapter.h
@@ -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_
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index d88937941b..5157237627 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -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
diff --git a/webrtc/video/video_receive_stream.h b/webrtc/video/video_receive_stream.h
index bf6f9db79c..8a23a10e10 100644
--- a/webrtc/video/video_receive_stream.h
+++ b/webrtc/video/video_receive_stream.h
@@ -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_;
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 5b8c23c8c9..b5fec72d9f 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -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
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index d0da69f4da..0881d91817 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -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_;
diff --git a/webrtc/video/webrtc_video.gypi b/webrtc/video/webrtc_video.gypi
index e26db0b98a..82e17f461e 100644
--- a/webrtc/video/webrtc_video.gypi
+++ b/webrtc/video/webrtc_video.gypi
@@ -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',
diff --git a/webrtc/video_engine/include/vie_image_process.h b/webrtc/video_engine/include/vie_image_process.h
index 9a12748e25..5006eda209 100644
--- a/webrtc/video_engine/include/vie_image_process.h
+++ b/webrtc/video_engine/include/vie_image_process.h
@@ -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;
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
index aa86673c9f..4a85a18586 100644
--- a/webrtc/video_engine/vie_channel.cc
+++ b/webrtc/video_engine/vie_channel.cc
@@ -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,
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
index 3b37140508..f6bc3fc83e 100644
--- a/webrtc/video_engine/vie_channel.h
+++ b/webrtc/video_engine/vie_channel.h
@@ -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);
diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc
index 9733a89848..ce13b1a672 100644
--- a/webrtc/video_engine/vie_encoder.cc
+++ b/webrtc/video_engine/vie_encoder.cc
@@ -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) {
}
diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h
index 73f84af7fc..cd8328e82e 100644
--- a/webrtc/video_engine/vie_encoder.h
+++ b/webrtc/video_engine/vie_encoder.h
@@ -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,
diff --git a/webrtc/video_engine/vie_image_process_impl.cc b/webrtc/video_engine/vie_image_process_impl.cc
index 92fe697627..b10e774a3e 100644
--- a/webrtc/video_engine/vie_image_process_impl.cc
+++ b/webrtc/video_engine/vie_image_process_impl.cc
@@ -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) {
diff --git a/webrtc/video_engine/vie_image_process_impl.h b/webrtc/video_engine/vie_image_process_impl.h
index 9b43e7ed06..74a7ff0372 100644
--- a/webrtc/video_engine/vie_image_process_impl.h
+++ b/webrtc/video_engine/vie_image_process_impl.h
@@ -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;
diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h
index 85d7519cc1..2358042e5a 100644
--- a/webrtc/video_send_stream.h
+++ b/webrtc/video_send_stream.h
@@ -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.