Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(536)

Side by Side Diff: media/filters/vp9_bool_decoder.cc

Issue 2133993002: Parse VP9 compressed header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implement VP9 compressed header parsing Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698