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 |