| 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 <deque> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 #define fourcc(a, b, c, d) \ | 44 #define fourcc(a, b, c, d) \ |
| 45 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \ | 45 (((uint32_t)(a) << 0) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | \ |
| 46 ((uint32_t)(d) << 24)) | 46 ((uint32_t)(d) << 24)) |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 double clamp(double min, double max, double value) { | 50 double clamp(double min, double max, double value) { |
| 51 return std::max(std::min(value, max), min); | 51 return std::max(std::min(value, max), min); |
| 52 } | 52 } |
| 53 | 53 |
| 54 std::string ToUpperString(const std::string& str) { |
| 55 std::string ret; |
| 56 for (uint32_t i = 0; i < str.size(); i++) |
| 57 ret.push_back(static_cast<char>(toupper(str[i]))); |
| 58 return ret; |
| 59 } |
| 60 |
| 54 // IVF container writer. It is possible to parse H264 bitstream using | 61 // IVF container writer. It is possible to parse H264 bitstream using |
| 55 // NAL units but for VP8 we need a container to at least find encoded | 62 // NAL units but for VP8 we need a container to at least find encoded |
| 56 // pictures as well as the picture sizes. | 63 // pictures as well as the picture sizes. |
| 57 class IVFWriter { | 64 class IVFWriter { |
| 58 public: | 65 public: |
| 59 IVFWriter() {} | 66 IVFWriter() {} |
| 60 ~IVFWriter() {} | 67 ~IVFWriter() {} |
| 61 | 68 |
| 62 uint32_t GetFileHeaderSize() const { return 32; } | 69 uint32_t GetFileHeaderSize() const { return 32; } |
| 63 uint32_t GetFrameHeaderSize() const { return 12; } | 70 uint32_t GetFrameHeaderSize() const { return 12; } |
| 64 uint32_t WriteFileHeader(uint8_t* mem, int32_t width, int32_t height); | 71 uint32_t WriteFileHeader(uint8_t* mem, |
| 72 const std::string& codec, |
| 73 int32_t width, |
| 74 int32_t height); |
| 65 uint32_t WriteFrameHeader(uint8_t* mem, uint64_t pts, size_t frame_size); | 75 uint32_t WriteFrameHeader(uint8_t* mem, uint64_t pts, size_t frame_size); |
| 66 | 76 |
| 67 private: | 77 private: |
| 68 void PutLE16(uint8_t* mem, int val) const { | 78 void PutLE16(uint8_t* mem, int val) const { |
| 69 mem[0] = (val >> 0) & 0xff; | 79 mem[0] = (val >> 0) & 0xff; |
| 70 mem[1] = (val >> 8) & 0xff; | 80 mem[1] = (val >> 8) & 0xff; |
| 71 } | 81 } |
| 72 void PutLE32(uint8_t* mem, int val) const { | 82 void PutLE32(uint8_t* mem, int val) const { |
| 73 mem[0] = (val >> 0) & 0xff; | 83 mem[0] = (val >> 0) & 0xff; |
| 74 mem[1] = (val >> 8) & 0xff; | 84 mem[1] = (val >> 8) & 0xff; |
| 75 mem[2] = (val >> 16) & 0xff; | 85 mem[2] = (val >> 16) & 0xff; |
| 76 mem[3] = (val >> 24) & 0xff; | 86 mem[3] = (val >> 24) & 0xff; |
| 77 } | 87 } |
| 78 }; | 88 }; |
| 79 | 89 |
| 80 uint32_t IVFWriter::WriteFileHeader(uint8_t* mem, | 90 uint32_t IVFWriter::WriteFileHeader(uint8_t* mem, |
| 91 const std::string& codec, |
| 81 int32_t width, | 92 int32_t width, |
| 82 int32_t height) { | 93 int32_t height) { |
| 83 mem[0] = 'D'; | 94 mem[0] = 'D'; |
| 84 mem[1] = 'K'; | 95 mem[1] = 'K'; |
| 85 mem[2] = 'I'; | 96 mem[2] = 'I'; |
| 86 mem[3] = 'F'; | 97 mem[3] = 'F'; |
| 87 PutLE16(mem + 4, 0); // version | 98 PutLE16(mem + 4, 0); // version |
| 88 PutLE16(mem + 6, 32); // header size | 99 PutLE16(mem + 6, 32); // header size |
| 89 PutLE32(mem + 8, fourcc('V', 'P', '8', '0')); // fourcc | 100 PutLE32(mem + 8, fourcc(codec[0], codec[1], codec[2], '0')); // fourcc |
| 90 PutLE16(mem + 12, static_cast<uint16_t>(width)); // width | 101 PutLE16(mem + 12, static_cast<uint16_t>(width)); // width |
| 91 PutLE16(mem + 14, static_cast<uint16_t>(height)); // height | 102 PutLE16(mem + 14, static_cast<uint16_t>(height)); // height |
| 92 PutLE32(mem + 16, 1000); // rate | 103 PutLE32(mem + 16, 1000); // rate |
| 93 PutLE32(mem + 20, 1); // scale | 104 PutLE32(mem + 20, 1); // scale |
| 94 PutLE32(mem + 24, 0xffffffff); // length | 105 PutLE32(mem + 24, 0xffffffff); // length |
| 95 PutLE32(mem + 28, 0); // unused | 106 PutLE32(mem + 28, 0); // unused |
| 96 | 107 |
| 97 return 32; | 108 return 32; |
| 98 } | 109 } |
| 99 | 110 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 uint32_t data_offset = 0; | 556 uint32_t data_offset = 0; |
| 546 if (video_profile_ == PP_VIDEOPROFILE_VP8_ANY || | 557 if (video_profile_ == PP_VIDEOPROFILE_VP8_ANY || |
| 547 video_profile_ == PP_VIDEOPROFILE_VP9_ANY) { | 558 video_profile_ == PP_VIDEOPROFILE_VP9_ANY) { |
| 548 uint32_t frame_offset = 0; | 559 uint32_t frame_offset = 0; |
| 549 if (encoded_frames_ == 1) { | 560 if (encoded_frames_ == 1) { |
| 550 array_buffer = pp::VarArrayBuffer( | 561 array_buffer = pp::VarArrayBuffer( |
| 551 size + ivf_writer_.GetFileHeaderSize() + | 562 size + ivf_writer_.GetFileHeaderSize() + |
| 552 ivf_writer_.GetFrameHeaderSize()); | 563 ivf_writer_.GetFrameHeaderSize()); |
| 553 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); | 564 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); |
| 554 frame_offset = ivf_writer_.WriteFileHeader( | 565 frame_offset = ivf_writer_.WriteFileHeader( |
| 555 data_ptr, frame_size_.width(), frame_size_.height()); | 566 data_ptr, ToUpperString(VideoProfileToString(video_profile_)), |
| 567 frame_size_.width(), frame_size_.height()); |
| 556 } else { | 568 } else { |
| 557 array_buffer = pp::VarArrayBuffer( | 569 array_buffer = pp::VarArrayBuffer( |
| 558 size + ivf_writer_.GetFrameHeaderSize()); | 570 size + ivf_writer_.GetFrameHeaderSize()); |
| 559 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); | 571 data_ptr = static_cast<uint8_t*>(array_buffer.Map()); |
| 560 } | 572 } |
| 561 uint64_t timestamp = frames_timestamps_.front(); | 573 uint64_t timestamp = frames_timestamps_.front(); |
| 562 frames_timestamps_.pop_front(); | 574 frames_timestamps_.pop_front(); |
| 563 data_offset = | 575 data_offset = |
| 564 frame_offset + | 576 frame_offset + |
| 565 ivf_writer_.WriteFrameHeader(data_ptr + frame_offset, timestamp, size); | 577 ivf_writer_.WriteFrameHeader(data_ptr + frame_offset, timestamp, size); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 } | 609 } |
| 598 | 610 |
| 599 } // anonymous namespace | 611 } // anonymous namespace |
| 600 | 612 |
| 601 namespace pp { | 613 namespace pp { |
| 602 // Factory function for your specialization of the Module object. | 614 // Factory function for your specialization of the Module object. |
| 603 Module* CreateModule() { | 615 Module* CreateModule() { |
| 604 return new VideoEncoderModule(); | 616 return new VideoEncoderModule(); |
| 605 } | 617 } |
| 606 } // namespace pp | 618 } // namespace pp |
| OLD | NEW |