OLD | NEW |
---|---|
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 28 matching lines...) Expand all Loading... | |
39 // include-guards), make sure this is the last file #include'd in this file. | 39 // include-guards), make sure this is the last file #include'd in this file. |
40 #undef NDEBUG | 40 #undef NDEBUG |
41 #include <assert.h> | 41 #include <assert.h> |
42 | 42 |
43 #define fourcc(a, b, c, d) \ | 43 #define fourcc(a, b, c, d) \ |
44 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \ | 44 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \ |
45 ((uint32_t)(d) << 24)) | 45 ((uint32_t)(d) << 24)) |
46 | 46 |
47 namespace { | 47 namespace { |
48 | 48 |
49 double clamp(double min, double max, double value) { | |
50 return std::max(std::min(value, max), min); | |
51 } | |
52 | |
49 // IVF container writer. It is possible to parse H264 bitstream using | 53 // IVF container writer. It is possible to parse H264 bitstream using |
50 // NAL units but for VP8 we need a container to at least find encoded | 54 // NAL units but for VP8 we need a container to at least find encoded |
51 // pictures as well as the picture sizes. | 55 // pictures as well as the picture sizes. |
52 class IVFWriter { | 56 class IVFWriter { |
53 public: | 57 public: |
54 IVFWriter() {} | 58 IVFWriter() {} |
55 ~IVFWriter() {} | 59 ~IVFWriter() {} |
56 | 60 |
57 uint32_t GetFileHeaderSize() const { return 32; } | 61 uint32_t GetFileHeaderSize() const { return 32; } |
58 uint32_t GetFrameHeaderSize() const { return 12; } | 62 uint32_t GetFrameHeaderSize() const { return 12; } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 | 158 |
155 void PostDataMessage(const void* buffer, uint32_t size); | 159 void PostDataMessage(const void* buffer, uint32_t size); |
156 | 160 |
157 typedef std::map<std::string, PP_VideoProfile> VideoProfileFromStringMap; | 161 typedef std::map<std::string, PP_VideoProfile> VideoProfileFromStringMap; |
158 VideoProfileFromStringMap profile_from_string_; | 162 VideoProfileFromStringMap profile_from_string_; |
159 | 163 |
160 typedef std::map<PP_VideoProfile, std::string> VideoProfileToStringMap; | 164 typedef std::map<PP_VideoProfile, std::string> VideoProfileToStringMap; |
161 VideoProfileToStringMap profile_to_string_; | 165 VideoProfileToStringMap profile_to_string_; |
162 | 166 |
163 bool is_encoding_; | 167 bool is_encoding_; |
168 bool is_encode_ticking_; | |
164 bool is_receiving_track_frames_; | 169 bool is_receiving_track_frames_; |
165 | 170 |
166 pp::VideoEncoder video_encoder_; | 171 pp::VideoEncoder video_encoder_; |
167 pp::MediaStreamVideoTrack video_track_; | 172 pp::MediaStreamVideoTrack video_track_; |
168 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; | 173 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; |
169 | 174 |
170 PP_VideoProfile video_profile_; | 175 PP_VideoProfile video_profile_; |
171 PP_VideoFrame_Format frame_format_; | 176 PP_VideoFrame_Format frame_format_; |
172 | 177 |
173 pp::Size requested_size_; | 178 pp::Size requested_size_; |
174 pp::Size frame_size_; | 179 pp::Size frame_size_; |
175 pp::Size encoder_size_; | 180 pp::Size encoder_size_; |
176 uint32_t encoded_frames_; | 181 uint32_t encoded_frames_; |
177 | 182 |
178 pp::VideoFrame current_track_frame_; | 183 pp::VideoFrame current_track_frame_; |
179 | 184 |
180 IVFWriter ivf_writer_; | 185 IVFWriter ivf_writer_; |
181 | 186 |
182 PP_Time last_encode_tick_; | 187 PP_Time last_encode_tick_; |
183 }; | 188 }; |
184 | 189 |
185 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, | 190 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, |
186 pp::Module* module) | 191 pp::Module* module) |
187 : pp::Instance(instance), | 192 : pp::Instance(instance), |
188 is_encoding_(false), | 193 is_encoding_(false), |
194 is_encode_ticking_(false), | |
189 callback_factory_(this), | 195 callback_factory_(this), |
190 #if defined(USE_VP8_INSTEAD_OF_H264) | 196 #if defined(USE_VP8_INSTEAD_OF_H264) |
191 video_profile_(PP_VIDEOPROFILE_VP8_ANY), | 197 video_profile_(PP_VIDEOPROFILE_VP8_ANY), |
192 #else | 198 #else |
193 video_profile_(PP_VIDEOPROFILE_H264MAIN), | 199 video_profile_(PP_VIDEOPROFILE_H264MAIN), |
194 #endif | 200 #endif |
195 frame_format_(PP_VIDEOFRAME_FORMAT_I420), | 201 frame_format_(PP_VIDEOFRAME_FORMAT_I420), |
196 encoded_frames_(0), | 202 encoded_frames_(0), |
197 last_encode_tick_(0) { | 203 last_encode_tick_(0) { |
198 InitializeVideoProfiles(); | 204 InitializeVideoProfiles(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 | 339 |
334 if (encoder_size_ != frame_size_) | 340 if (encoder_size_ != frame_size_) |
335 ConfigureTrack(); | 341 ConfigureTrack(); |
336 else { | 342 else { |
337 StartTrackFrames(); | 343 StartTrackFrames(); |
338 ScheduleNextEncode(); | 344 ScheduleNextEncode(); |
339 } | 345 } |
340 } | 346 } |
341 | 347 |
342 void VideoEncoderInstance::ScheduleNextEncode() { | 348 void VideoEncoderInstance::ScheduleNextEncode() { |
349 // Avoid scheduling more than once at a time. | |
350 if (is_encode_ticking_) | |
351 return; | |
352 | |
343 PP_Time now = pp::Module::Get()->core()->GetTime(); | 353 PP_Time now = pp::Module::Get()->core()->GetTime(); |
354 PP_Time tick = 1.0 / 30; | |
355 PP_Time delta = | |
binji
2015/06/30 17:02:02
This produces a constant value for delta:
1. The
llandwerlin-old
2015/06/30 17:15:22
Thanks, just clamping once between [0, tick].
| |
356 tick - clamp(0, tick, clamp(0, tick, now - last_encode_tick_) - tick); | |
357 | |
344 pp::Module::Get()->core()->CallOnMainThread( | 358 pp::Module::Get()->core()->CallOnMainThread( |
345 std::min(std::max(now - last_encode_tick_, 0.0), 1000.0 / 30), | 359 delta * 1000, |
346 callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick), | 360 callback_factory_.NewCallback(&VideoEncoderInstance::GetEncoderFrameTick), |
347 0); | 361 0); |
362 | |
348 last_encode_tick_ = now; | 363 last_encode_tick_ = now; |
364 is_encode_ticking_ = true; | |
349 } | 365 } |
350 | 366 |
351 void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) { | 367 void VideoEncoderInstance::GetEncoderFrameTick(int32_t result) { |
368 is_encode_ticking_ = false; | |
369 | |
352 if (is_encoding_) { | 370 if (is_encoding_) { |
353 if (!current_track_frame_.is_null()) { | 371 if (!current_track_frame_.is_null()) { |
354 pp::VideoFrame frame = current_track_frame_; | 372 pp::VideoFrame frame = current_track_frame_; |
355 current_track_frame_.detach(); | 373 current_track_frame_.detach(); |
356 GetEncoderFrame(frame); | 374 GetEncoderFrame(frame); |
357 } | 375 } |
358 ScheduleNextEncode(); | 376 ScheduleNextEncode(); |
359 } | 377 } |
360 } | 378 } |
361 | 379 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 } | 589 } |
572 | 590 |
573 } // anonymous namespace | 591 } // anonymous namespace |
574 | 592 |
575 namespace pp { | 593 namespace pp { |
576 // Factory function for your specialization of the Module object. | 594 // Factory function for your specialization of the Module object. |
577 Module* CreateModule() { | 595 Module* CreateModule() { |
578 return new VideoEncoderModule(); | 596 return new VideoEncoderModule(); |
579 } | 597 } |
580 } // namespace pp | 598 } // namespace pp |
OLD | NEW |