Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: ppapi/examples/video_encode/video_encode.cc

Issue 1218513003: ppapi: VideoEncoder: prevent scheduling encoding multiple times (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do not clamp twice Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <math.h> 5 #include <math.h>
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <iostream> 10 #include <iostream>
(...skipping 26 matching lines...) Expand all
37 // include-guards), make sure this is the last file #include'd in this file. 37 // include-guards), make sure this is the last file #include'd in this file.
38 #undef NDEBUG 38 #undef NDEBUG
39 #include <assert.h> 39 #include <assert.h>
40 40
41 #define fourcc(a, b, c, d) \ 41 #define fourcc(a, b, c, d) \
42 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \ 42 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \
43 ((uint32_t)(d) << 24)) 43 ((uint32_t)(d) << 24))
44 44
45 namespace { 45 namespace {
46 46
47 double clamp(double min, double max, double value) {
48 return std::max(std::min(value, max), min);
49 }
50
47 // IVF container writer. It is possible to parse H264 bitstream using 51 // IVF container writer. It is possible to parse H264 bitstream using
48 // NAL units but for VP8 we need a container to at least find encoded 52 // NAL units but for VP8 we need a container to at least find encoded
49 // pictures as well as the picture sizes. 53 // pictures as well as the picture sizes.
50 class IVFWriter { 54 class IVFWriter {
51 public: 55 public:
52 IVFWriter() {} 56 IVFWriter() {}
53 ~IVFWriter() {} 57 ~IVFWriter() {}
54 58
55 uint32_t GetFileHeaderSize() const { return 32; } 59 uint32_t GetFileHeaderSize() const { return 32; }
56 uint32_t GetFrameHeaderSize() const { return 12; } 60 uint32_t GetFrameHeaderSize() const { return 12; }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 void PostDataMessage(const void* buffer, uint32_t size); 157 void PostDataMessage(const void* buffer, uint32_t size);
154 void PostSignalMessage(const char* name); 158 void PostSignalMessage(const char* name);
155 159
156 typedef std::map<std::string, PP_VideoProfile> VideoProfileFromStringMap; 160 typedef std::map<std::string, PP_VideoProfile> VideoProfileFromStringMap;
157 VideoProfileFromStringMap profile_from_string_; 161 VideoProfileFromStringMap profile_from_string_;
158 162
159 typedef std::map<PP_VideoProfile, std::string> VideoProfileToStringMap; 163 typedef std::map<PP_VideoProfile, std::string> VideoProfileToStringMap;
160 VideoProfileToStringMap profile_to_string_; 164 VideoProfileToStringMap profile_to_string_;
161 165
162 bool is_encoding_; 166 bool is_encoding_;
167 bool is_encode_ticking_;
163 bool is_receiving_track_frames_; 168 bool is_receiving_track_frames_;
164 169
165 pp::VideoEncoder video_encoder_; 170 pp::VideoEncoder video_encoder_;
166 pp::MediaStreamVideoTrack video_track_; 171 pp::MediaStreamVideoTrack video_track_;
167 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; 172 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_;
168 173
169 PP_VideoProfile video_profile_; 174 PP_VideoProfile video_profile_;
170 PP_VideoFrame_Format frame_format_; 175 PP_VideoFrame_Format frame_format_;
171 176
172 pp::Size requested_size_; 177 pp::Size requested_size_;
173 pp::Size frame_size_; 178 pp::Size frame_size_;
174 pp::Size encoder_size_; 179 pp::Size encoder_size_;
175 uint32_t encoded_frames_; 180 uint32_t encoded_frames_;
176 181
177 pp::VideoFrame current_track_frame_; 182 pp::VideoFrame current_track_frame_;
178 183
179 IVFWriter ivf_writer_; 184 IVFWriter ivf_writer_;
180 185
181 PP_Time last_encode_tick_; 186 PP_Time last_encode_tick_;
182 }; 187 };
183 188
184 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, 189 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance,
185 pp::Module* module) 190 pp::Module* module)
186 : pp::Instance(instance), 191 : pp::Instance(instance),
187 is_encoding_(false), 192 is_encoding_(false),
193 is_encode_ticking_(false),
188 callback_factory_(this), 194 callback_factory_(this),
189 #if defined(USE_VP8_INSTEAD_OF_H264) 195 #if defined(USE_VP8_INSTEAD_OF_H264)
190 video_profile_(PP_VIDEOPROFILE_VP8_ANY), 196 video_profile_(PP_VIDEOPROFILE_VP8_ANY),
191 #else 197 #else
192 video_profile_(PP_VIDEOPROFILE_H264MAIN), 198 video_profile_(PP_VIDEOPROFILE_H264MAIN),
193 #endif 199 #endif
194 frame_format_(PP_VIDEOFRAME_FORMAT_I420), 200 frame_format_(PP_VIDEOFRAME_FORMAT_I420),
195 encoded_frames_(0), 201 encoded_frames_(0),
196 last_encode_tick_(0) { 202 last_encode_tick_(0) {
197 InitializeVideoProfiles(); 203 InitializeVideoProfiles();
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 342
337 if (encoder_size_ != frame_size_) 343 if (encoder_size_ != frame_size_)
338 ConfigureTrack(); 344 ConfigureTrack();
339 else { 345 else {
340 StartTrackFrames(); 346 StartTrackFrames();
341 ScheduleNextEncode(); 347 ScheduleNextEncode();
342 } 348 }
343 } 349 }
344 350
345 void VideoEncoderInstance::ScheduleNextEncode() { 351 void VideoEncoderInstance::ScheduleNextEncode() {
352 // Avoid scheduling more than once at a time.
353 if (is_encode_ticking_)
354 return;
355
346 PP_Time now = pp::Module::Get()->core()->GetTime(); 356 PP_Time now = pp::Module::Get()->core()->GetTime();
357 PP_Time tick = 1.0 / 30;
358 // If the callback was triggered late, we need to account for that
359 // delay for the next tick.
360 PP_Time delta = tick - clamp(0, tick, now - last_encode_tick_ - tick);
361
347 pp::Module::Get()->core()->CallOnMainThread( 362 pp::Module::Get()->core()->CallOnMainThread(
348 std::min(std::max(now - last_encode_tick_, 0.0), 1000.0 / 30), 363 delta * 1000,
349 callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick), 364 callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick),
350 0); 365 0);
366
351 last_encode_tick_ = now; 367 last_encode_tick_ = now;
368 is_encode_ticking_ = true;
352 } 369 }
353 370
354 void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) { 371 void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) {
372 is_encode_ticking_ = false;
373
355 if (is_encoding_) { 374 if (is_encoding_) {
356 if (!current_track_frame_.is_null()) { 375 if (!current_track_frame_.is_null()) {
357 pp::VideoFrame frame = current_track_frame_; 376 pp::VideoFrame frame = current_track_frame_;
358 current_track_frame_.detach(); 377 current_track_frame_.detach();
359 GetEncoderFrame(frame); 378 GetEncoderFrame(frame);
360 } 379 }
361 ScheduleNextEncode(); 380 ScheduleNextEncode();
362 } 381 }
363 } 382 }
364 383
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 595 }
577 596
578 } // anonymous namespace 597 } // anonymous namespace
579 598
580 namespace pp { 599 namespace pp {
581 // Factory function for your specialization of the Module object. 600 // Factory function for your specialization of the Module object.
582 Module* CreateModule() { 601 Module* CreateModule() {
583 return new VideoEncoderModule(); 602 return new VideoEncoderModule();
584 } 603 }
585 } // namespace pp 604 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698