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 <deque> |
10 #include <iostream> | 11 #include <iostream> |
11 #include <map> | 12 #include <map> |
12 #include <sstream> | 13 #include <sstream> |
13 #include <vector> | 14 #include <vector> |
14 | 15 |
15 #include "ppapi/c/pp_errors.h" | 16 #include "ppapi/c/pp_errors.h" |
16 #include "ppapi/c/ppb_console.h" | 17 #include "ppapi/c/ppb_console.h" |
17 #include "ppapi/cpp/input_event.h" | 18 #include "ppapi/cpp/input_event.h" |
18 #include "ppapi/cpp/instance.h" | 19 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/media_stream_video_track.h" | 20 #include "ppapi/cpp/media_stream_video_track.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 int32_t height) { | 82 int32_t height) { |
82 mem[0] = 'D'; | 83 mem[0] = 'D'; |
83 mem[1] = 'K'; | 84 mem[1] = 'K'; |
84 mem[2] = 'I'; | 85 mem[2] = 'I'; |
85 mem[3] = 'F'; | 86 mem[3] = 'F'; |
86 PutLE16(mem + 4, 0); // version | 87 PutLE16(mem + 4, 0); // version |
87 PutLE16(mem + 6, 32); // header size | 88 PutLE16(mem + 6, 32); // header size |
88 PutLE32(mem + 8, fourcc('V', 'P', '8', '0')); // fourcc | 89 PutLE32(mem + 8, fourcc('V', 'P', '8', '0')); // fourcc |
89 PutLE16(mem + 12, static_cast<uint16_t>(width)); // width | 90 PutLE16(mem + 12, static_cast<uint16_t>(width)); // width |
90 PutLE16(mem + 14, static_cast<uint16_t>(height)); // height | 91 PutLE16(mem + 14, static_cast<uint16_t>(height)); // height |
91 PutLE32(mem + 16, 30); // rate | 92 PutLE32(mem + 16, 1000); // rate |
92 PutLE32(mem + 20, 1); // scale | 93 PutLE32(mem + 20, 1); // scale |
93 PutLE32(mem + 24, 0xffffffff); // length | 94 PutLE32(mem + 24, 0xffffffff); // length |
94 PutLE32(mem + 28, 0); // unused | 95 PutLE32(mem + 28, 0); // unused |
95 | 96 |
96 return 32; | 97 return 32; |
97 } | 98 } |
98 | 99 |
99 uint32_t IVFWriter::WriteFrameHeader(uint8_t* mem, | 100 uint32_t IVFWriter::WriteFrameHeader(uint8_t* mem, |
100 uint64_t pts, | 101 uint64_t pts, |
101 size_t frame_size) { | 102 size_t frame_size) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; | 174 pp::CompletionCallbackFactory<VideoEncoderInstance> callback_factory_; |
174 | 175 |
175 PP_VideoProfile video_profile_; | 176 PP_VideoProfile video_profile_; |
176 PP_VideoFrame_Format frame_format_; | 177 PP_VideoFrame_Format frame_format_; |
177 | 178 |
178 pp::Size requested_size_; | 179 pp::Size requested_size_; |
179 pp::Size frame_size_; | 180 pp::Size frame_size_; |
180 pp::Size encoder_size_; | 181 pp::Size encoder_size_; |
181 uint32_t encoded_frames_; | 182 uint32_t encoded_frames_; |
182 | 183 |
| 184 std::deque<uint64_t> frames_timestamps_; |
| 185 |
183 pp::VideoFrame current_track_frame_; | 186 pp::VideoFrame current_track_frame_; |
184 | 187 |
185 IVFWriter ivf_writer_; | 188 IVFWriter ivf_writer_; |
186 | 189 |
187 PP_Time last_encode_tick_; | 190 PP_Time last_encode_tick_; |
188 }; | 191 }; |
189 | 192 |
190 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, | 193 VideoEncoderInstance::VideoEncoderInstance(PP_Instance instance, |
191 pp::Module* module) | 194 pp::Module* module) |
192 : pp::Instance(instance), | 195 : pp::Instance(instance), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 int32_t idx = 0; | 304 int32_t idx = 0; |
302 for (uint32_t i = 0; i < profiles.size(); i++) { | 305 for (uint32_t i = 0; i < profiles.size(); i++) { |
303 const PP_VideoProfileDescription& profile = profiles[i]; | 306 const PP_VideoProfileDescription& profile = profiles[i]; |
304 js_profiles.Set(idx++, pp::Var(VideoProfileToString(profile.profile))); | 307 js_profiles.Set(idx++, pp::Var(VideoProfileToString(profile.profile))); |
305 } | 308 } |
306 PostMessage(dict); | 309 PostMessage(dict); |
307 } | 310 } |
308 | 311 |
309 void VideoEncoderInstance::StartEncoder() { | 312 void VideoEncoderInstance::StartEncoder() { |
310 video_encoder_ = pp::VideoEncoder(this); | 313 video_encoder_ = pp::VideoEncoder(this); |
| 314 frames_timestamps_.clear(); |
311 | 315 |
312 int32_t error = video_encoder_.Initialize( | 316 int32_t error = video_encoder_.Initialize( |
313 frame_format_, frame_size_, video_profile_, 2000000, | 317 frame_format_, frame_size_, video_profile_, 2000000, |
314 PP_HARDWAREACCELERATION_WITHFALLBACK, | 318 PP_HARDWAREACCELERATION_WITHFALLBACK, |
315 callback_factory_.NewCallback( | 319 callback_factory_.NewCallback( |
316 &VideoEncoderInstance::OnInitializedEncoder)); | 320 &VideoEncoderInstance::OnInitializedEncoder)); |
317 if (error != PP_OK_COMPLETIONPENDING) { | 321 if (error != PP_OK_COMPLETIONPENDING) { |
318 LogError(error, "Cannot initialize encoder"); | 322 LogError(error, "Cannot initialize encoder"); |
319 return; | 323 return; |
320 } | 324 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 LogError(PP_ERROR_FAILED, oss.str()); | 422 LogError(PP_ERROR_FAILED, oss.str()); |
419 return PP_ERROR_FAILED; | 423 return PP_ERROR_FAILED; |
420 } | 424 } |
421 | 425 |
422 dest.SetTimestamp(src.GetTimestamp()); | 426 dest.SetTimestamp(src.GetTimestamp()); |
423 memcpy(dest.GetDataBuffer(), src.GetDataBuffer(), src.GetDataBufferSize()); | 427 memcpy(dest.GetDataBuffer(), src.GetDataBuffer(), src.GetDataBufferSize()); |
424 return PP_OK; | 428 return PP_OK; |
425 } | 429 } |
426 | 430 |
427 void VideoEncoderInstance::EncodeFrame(const pp::VideoFrame& frame) { | 431 void VideoEncoderInstance::EncodeFrame(const pp::VideoFrame& frame) { |
| 432 frames_timestamps_.push_back( |
| 433 static_cast<uint64_t>(frame.GetTimestamp() * 1000)); |
428 video_encoder_.Encode( | 434 video_encoder_.Encode( |
429 frame, PP_FALSE, | 435 frame, PP_FALSE, |
430 callback_factory_.NewCallback(&VideoEncoderInstance::OnEncodeDone)); | 436 callback_factory_.NewCallback(&VideoEncoderInstance::OnEncodeDone)); |
431 } | 437 } |
432 | 438 |
433 void VideoEncoderInstance::OnEncodeDone(int32_t result) { | 439 void VideoEncoderInstance::OnEncodeDone(int32_t result) { |
434 if (result == PP_ERROR_ABORTED) | 440 if (result == PP_ERROR_ABORTED) |
435 return; | 441 return; |
436 if (result != PP_OK) | 442 if (result != PP_OK) |
437 LogError(result, "Encode failed"); | 443 LogError(result, "Encode failed"); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 size + ivf_writer_.GetFileHeaderSize() + | 551 size + ivf_writer_.GetFileHeaderSize() + |
546 ivf_writer_.GetFrameHeaderSize()); | 552 ivf_writer_.GetFrameHeaderSize()); |
547 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); | 553 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); |
548 frame_offset = ivf_writer_.WriteFileHeader( | 554 frame_offset = ivf_writer_.WriteFileHeader( |
549 data_ptr, frame_size_.width(), frame_size_.height()); | 555 data_ptr, frame_size_.width(), frame_size_.height()); |
550 } else { | 556 } else { |
551 array_buffer = pp::VarArrayBuffer( | 557 array_buffer = pp::VarArrayBuffer( |
552 size + ivf_writer_.GetFrameHeaderSize()); | 558 size + ivf_writer_.GetFrameHeaderSize()); |
553 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); | 559 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); |
554 } | 560 } |
555 data_offset = frame_offset + | 561 uint64_t timestamp = frames_timestamps_.front(); |
556 ivf_writer_.WriteFrameHeader(data_ptr + frame_offset, | 562 frames_timestamps_.pop_front(); |
557 encoded_frames_, | 563 data_offset = |
558 size); | 564 frame_offset + |
| 565 ivf_writer_.WriteFrameHeader(data_ptr + frame_offset, timestamp, size); |
559 } else { | 566 } else { |
560 array_buffer = pp::VarArrayBuffer(size); | 567 array_buffer = pp::VarArrayBuffer(size); |
561 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); | 568 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); |
562 } | 569 } |
563 | 570 |
564 memcpy(data_ptr + data_offset, buffer, size); | 571 memcpy(data_ptr + data_offset, buffer, size); |
565 array_buffer.Unmap(); | 572 array_buffer.Unmap(); |
566 dictionary.Set(pp::Var("data"), array_buffer); | 573 dictionary.Set(pp::Var("data"), array_buffer); |
567 | 574 |
568 PostMessage(dictionary); | 575 PostMessage(dictionary); |
(...skipping 21 matching lines...) Expand all Loading... |
590 } | 597 } |
591 | 598 |
592 } // anonymous namespace | 599 } // anonymous namespace |
593 | 600 |
594 namespace pp { | 601 namespace pp { |
595 // Factory function for your specialization of the Module object. | 602 // Factory function for your specialization of the Module object. |
596 Module* CreateModule() { | 603 Module* CreateModule() { |
597 return new VideoEncoderModule(); | 604 return new VideoEncoderModule(); |
598 } | 605 } |
599 } // namespace pp | 606 } // namespace pp |
OLD | NEW |