OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/filters/vp9_bool_decoder.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "media/base/bit_reader.h" | |
9 | |
10 namespace media { | |
11 | |
12 namespace { | |
13 | |
14 const int kCountToShiftTo128[256] = { | |
Pawel Osciak
2016/08/04 10:20:18
Please add a comment what this is.
kcwu
2016/08/05 11:38:46
Done.
| |
15 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | |
16 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
17 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, | |
18 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
19 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
20 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
26 }; | |
27 } // namespace | |
28 | |
29 Vp9BoolDecoder::Vp9BoolDecoder() : valid_(true) {} | |
Pawel Osciak
2016/08/04 10:20:17
We could perhaps use class member initialization i
kcwu
2016/08/05 11:38:46
Done.
| |
30 | |
31 Vp9BoolDecoder::~Vp9BoolDecoder() {} | |
32 | |
33 // 9.2.1 Initialization process for Boolean decoder | |
34 bool Vp9BoolDecoder::Initialize(const uint8_t* data, size_t size) { | |
35 DCHECK(data); | |
36 reader_.reset(new BitReader(data, size)); | |
37 valid_ = true; | |
38 | |
39 if (size < 1) { | |
Pawel Osciak
2016/08/04 10:20:17
Perhaps we should check this before BitReader init
kcwu
2016/08/05 11:38:46
Done.
| |
40 DVLOG(1) << "input size of bool decoder shall be at least 1"; | |
41 valid_ = false; | |
42 return false; | |
43 } | |
44 | |
45 bool_value_ = 0; | |
46 count_to_fill_ = 8; | |
47 bool_range_ = 255; | |
48 Fill(); | |
Pawel Osciak
2016/08/04 10:20:17
I think ReadLiteral() will Fill() by itself, so pe
kcwu
2016/08/05 11:38:46
Done.
| |
49 if (ReadLiteral(1) != 0) { | |
50 DVLOG(1) << "marker bit should be 0"; | |
51 valid_ = false; | |
52 return false; | |
53 } | |
54 return true; | |
55 } | |
56 | |
57 // Fill at least |count_to_fill_| bits and prefill remain bits of |bool_value_| | |
58 // if data is enough. | |
59 void Vp9BoolDecoder::Fill() { | |
60 DCHECK_GE(count_to_fill_, 0); | |
61 | |
62 int bits_left = reader_->bits_available(); | |
Pawel Osciak
2016/08/04 10:20:18
Should all of these be size_t ?
kcwu
2016/08/05 11:38:46
Done.
| |
63 if (bits_left < count_to_fill_) { | |
64 valid_ = false; | |
65 DVLOG(1) << "Vp9BoolDecoder reads beyond the end of stream"; | |
66 return; | |
67 } | |
68 | |
69 DCHECK_LE(count_to_fill_, kBoolSize); | |
70 int max_bits_to_read = kBigBoolSize - kBoolSize + count_to_fill_; | |
71 int bits_to_read = std::min(max_bits_to_read, bits_left); | |
72 | |
73 BigBool data; | |
74 reader_->ReadBits(bits_to_read, &data); | |
75 bool_value_ |= data << (max_bits_to_read - bits_to_read); | |
76 count_to_fill_ -= bits_to_read; | |
77 } | |
78 | |
79 // 9.2.2 Boolean decoding process | |
80 bool Vp9BoolDecoder::ReadBool(int prob) { | |
81 DCHECK(reader_); | |
82 if (!valid_) | |
Pawel Osciak
2016/08/04 10:20:18
Should we be checking for valid_ here and in ReadL
kcwu
2016/08/05 11:38:46
This is intended behavior. So the caller doesn't n
| |
83 return false; | |
84 | |
85 if (count_to_fill_ > 0) { | |
86 Fill(); | |
87 if (!valid_) | |
Pawel Osciak
2016/08/04 10:20:18
Perhaps Fill() should just return a bool?
kcwu
2016/08/05 11:38:46
Done.
| |
88 return false; | |
89 } | |
90 | |
91 unsigned int split = (bool_range_ * prob + (256 - prob)) >> kBoolSize; | |
Pawel Osciak
2016/08/04 10:20:17
Would it be safer to use a fixed-length type?
kcwu
2016/08/05 11:38:46
|bool_range| is less than 256, thus |split| is les
| |
92 BigBool big_split = static_cast<BigBool>(split) << (kBigBoolSize - kBoolSize); | |
93 | |
94 bool bit; | |
95 if (bool_value_ < big_split) { | |
96 bool_range_ = split; | |
97 bit = false; | |
98 } else { | |
99 bool_range_ -= split; | |
100 bool_value_ -= big_split; | |
101 bit = true; | |
102 } | |
103 | |
104 // Need to fill |count| bits next time in order to make |bool_range_| >= | |
105 // 128. | |
106 DCHECK_LT(bool_range_, arraysize(kCountToShiftTo128)); | |
107 DCHECK_GT(bool_range_, 0u); | |
108 int count = kCountToShiftTo128[bool_range_]; | |
109 bool_range_ <<= count; | |
110 bool_value_ <<= count; | |
111 count_to_fill_ += count; | |
112 | |
113 return bit; | |
114 } | |
115 | |
116 // 9.2.4 Parsing process for read_literal | |
117 int Vp9BoolDecoder::ReadLiteral(int bits) { | |
118 DCHECK(reader_); | |
119 if (!valid_) | |
120 return 0; | |
121 | |
122 int x = 0; | |
Pawel Osciak
2016/08/04 10:20:17
Should this be a fixed-size type and also unsigned
kcwu
2016/08/05 11:38:46
I'm not sure what size it should be. Just use arbi
| |
123 for (int i = 0; i < bits; i++) | |
Pawel Osciak
2016/08/04 10:20:17
s/int/size_t/
kcwu
2016/08/05 11:38:47
Acknowledged.
| |
124 x = 2 * x + ReadBool(128); | |
125 | |
126 return x; | |
127 } | |
128 | |
129 bool Vp9BoolDecoder::ConsumePaddingBits() { | |
130 DCHECK(reader_); | |
131 int data; | |
132 | |
133 if (count_to_fill_ > reader_->bits_available()) { | |
134 // 9.2.2 Boolean decoding process | |
135 // Although we actually don't used the value, spec says the bitstream | |
136 // should have enough bits to fill bool range, this should never happend | |
Pawel Osciak
2016/08/04 10:20:17
s/happend/happen./ ?
kcwu
2016/08/05 11:38:46
Done.
| |
137 DVLOG(2) << "not enough bits in bitstream to fill bool range"; | |
138 return false; | |
139 } | |
140 | |
141 if (bool_value_ != 0) { | |
142 DVLOG(1) << "prefilled padding bits are not zero"; | |
143 return false; | |
144 } | |
145 while (reader_->bits_available() > 0) { | |
146 int size_to_read = | |
147 std::min(reader_->bits_available(), static_cast<int>(sizeof(data) * 8)); | |
148 reader_->ReadBits(size_to_read, &data); | |
149 if (data != 0) { | |
150 DVLOG(1) << "padding bits are not zero"; | |
151 return false; | |
152 } | |
153 } | |
154 return true; | |
155 } | |
156 | |
157 } // namespace media | |
OLD | NEW |