Index: native_client_sdk/src/examples/api/video_encode/video_encode.cc |
diff --git a/native_client_sdk/src/examples/api/video_encode/video_encode.cc b/native_client_sdk/src/examples/api/video_encode/video_encode.cc |
index fb43b37cd1f84741f70751129b4be9be5b903418..77dce0e2937fab50c9306b371ffee609ad9be626 100644 |
--- a/native_client_sdk/src/examples/api/video_encode/video_encode.cc |
+++ b/native_client_sdk/src/examples/api/video_encode/video_encode.cc |
@@ -46,6 +46,10 @@ |
namespace { |
+double clamp(double min, double max, double value) { |
+ return std::max(std::min(value, max), min); |
+} |
+ |
// IVF container writer. It is possible to parse H264 bitstream using |
// NAL units but for VP8 we need a container to at least find encoded |
// pictures as well as the picture sizes. |
@@ -161,6 +165,7 @@ class VideoEncoderInstance : public pp::Instance { |
VideoProfileToStringMap profile_to_string_; |
bool is_encoding_; |
+ bool is_encode_ticking_; |
bool is_receiving_track_frames_; |
pp::VideoEncoder video_encoder_; |
@@ -186,6 +191,7 @@ VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, |
pp::Module* module) |
: pp::Instance(instance), |
is_encoding_(false), |
+ is_encode_ticking_(false), |
callback_factory_(this), |
#if defined(USE_VP8_INSTEAD_OF_H264) |
video_profile_(PP_VIDEOPROFILE_VP8_ANY), |
@@ -340,15 +346,28 @@ void VideoEncoderInstance::OnInitializedEncoder(int32_t result) { |
} |
void VideoEncoderInstance::ScheduleNextEncode() { |
+ // Avoid scheduling more than once at a time. |
+ if (is_encode_ticking_) |
+ return; |
+ |
PP_Time now = pp::Module::Get()->core()->GetTime(); |
+ PP_Time tick = 1.0 / 30; |
+ // If the callback was triggered late, we need to account for that |
+ // delay for the next tick. |
+ PP_Time delta = tick - clamp(0, tick, now - last_encode_tick_ - tick); |
binji
2015/06/30 18:50:34
Just to be clear: this assumes the callback is nev
llandwerlin-old
2015/06/30 19:14:15
Yes, that's right. I assumed the implementation wo
|
+ |
pp::Module::Get()->core()->CallOnMainThread( |
- std::min(std::max(now - last_encode_tick_, 0.0), 1000.0 / 30), |
+ delta * 1000, |
callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick), |
0); |
+ |
last_encode_tick_ = now; |
+ is_encode_ticking_ = true; |
} |
void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) { |
+ is_encode_ticking_ = false; |
+ |
if (is_encoding_) { |
if (!current_track_frame_.is_null()) { |
pp::VideoFrame frame = current_track_frame_; |