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