Chromium Code Reviews| Index: media/formats/webm/opus_packet_builder.cc |
| diff --git a/media/formats/webm/opus_packet_builder.cc b/media/formats/webm/opus_packet_builder.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..76cf22128f2d0cc06c7a8af16be147ec99e3de00 |
| --- /dev/null |
| +++ b/media/formats/webm/opus_packet_builder.cc |
| @@ -0,0 +1,83 @@ |
| +#include "media/formats/webm/opus_packet_builder.h" |
| +#include "media/formats/webm/webm_cluster_parser.h" |
| + |
| +namespace media { |
| + |
| +// From Opus RFC. See https://tools.ietf.org/html/rfc6716#page-14 |
| +enum OpusConstants { |
| + kNumPossibleOpusConfigs = 32, |
| + kMinOpusPacketFrameCount = 1, |
| + kMaxOpusPacketFrameCount = 48 |
| +}; |
| + |
| +OpusPacket::OpusPacket(int config, int frame_count, bool is_VBR) { |
|
wolenetz
2015/02/05 23:05:00
narrow param types (uint8_t config and frame_count
chcunningham
2015/02/06 03:20:09
Done.
|
| + duration_ms_ = frame_count * |
|
wolenetz
2015/02/05 23:04:59
nit: protect borders (DCHECK fail for invalid conf
chcunningham
2015/02/06 03:20:09
Done. Decided to not allow invalid packets at this
|
| + WebMClusterParser::kOpusFrameDurationsMu[config] / |
| + static_cast<float>(1000); |
| + |
| + int frame_count_code; |
| + uint8_t frame_count_byte; |
| + |
| + if (frame_count == 1) { |
| + frame_count_code = 0; |
| + } else if (frame_count == 2) { |
| + frame_count_code = is_VBR ? 2 : 1; |
| + } else { |
| + frame_count_code = 3; |
| + frame_count_byte = (is_VBR ? 1 << 7 : 0) | frame_count; |
| + } |
| + |
| + // All opus packets must have TOC byte. |
| + uint8_t opus_toc_byte = (config << 3) | frame_count_code; |
| + data_.push_back(opus_toc_byte); |
| + |
| + // For code 3 packets, the number of frames is signaled in the "frame |
|
wolenetz
2015/02/05 23:04:59
For code 2 packets, the compressed length.. is als
chcunningham
2015/02/06 03:20:09
Clarified the comment that we're not really attemp
|
| + // count byte". |
| + if (frame_count_code == 3) { |
| + data_.push_back(frame_count_byte); |
| + } |
| + |
| + // Simulating encoded frame data. |
| + data_.push_back(static_cast<uint8_t>(0)); |
| +} |
| + |
| +OpusPacket::~OpusPacket() { |
| +} |
| + |
| +const uint8_t* OpusPacket::data() const { |
| + return &(data_[0]); |
| +} |
| + |
| +int OpusPacket::size() const { |
| + return data_.size(); |
| +} |
| + |
| +double OpusPacket::duration_ms() const { |
| + return duration_ms_; |
| +} |
| + |
| +ScopedVector<OpusPacket> BuildAllOpusPackets() { |
|
wolenetz
2015/02/05 23:04:59
Are there illegal Opus Packet config + frame_count
chcunningham
2015/02/06 03:20:09
Done.
|
| + ScopedVector<OpusPacket> opus_packets; |
| + |
| + for (int frame_count = kMinOpusPacketFrameCount; |
| + frame_count <= kMaxOpusPacketFrameCount; frame_count++) { |
| + for (int opus_config_num = 0; opus_config_num < kNumPossibleOpusConfigs; |
| + opus_config_num++) { |
| + bool is_VBR = false; |
|
wolenetz
2015/02/05 23:04:59
nit: is_VBR can be inlined in each of the two call
chcunningham
2015/02/06 03:20:09
I like this for self documenting the meaning of th
wolenetz
2015/02/06 19:48:01
Acknowledged.
|
| + opus_packets.push_back( |
| + new OpusPacket(opus_config_num, frame_count, is_VBR)); |
| + |
| + if (frame_count >= 2) { |
| + // Add another packet with VBR flag toggled. For frame counts >= 2, |
| + // VBR triggers changes to packet framing. |
| + is_VBR = true; |
| + opus_packets.push_back( |
| + new OpusPacket(opus_config_num, frame_count, is_VBR)); |
| + } |
| + } |
| + } |
| + |
| + return opus_packets.Pass(); |
| +} |
| + |
| +} // namespace media |