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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: media/filters/vp9_bool_decoder.cc
diff --git a/media/filters/vp9_bool_decoder.cc b/media/filters/vp9_bool_decoder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..138844218a8db70d8b41665be3ab6b5b183ada6a
--- /dev/null
+++ b/media/filters/vp9_bool_decoder.cc
@@ -0,0 +1,157 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/vp9_bool_decoder.h"
+
+#include "base/logging.h"
+#include "media/base/bit_reader.h"
+
+namespace media {
+
+namespace {
+
+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.
+ 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+} // namespace
+
+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.
+
+Vp9BoolDecoder::~Vp9BoolDecoder() {}
+
+// 9.2.1 Initialization process for Boolean decoder
+bool Vp9BoolDecoder::Initialize(const uint8_t* data, size_t size) {
+ DCHECK(data);
+ reader_.reset(new BitReader(data, size));
+ valid_ = true;
+
+ 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.
+ DVLOG(1) << "input size of bool decoder shall be at least 1";
+ valid_ = false;
+ return false;
+ }
+
+ bool_value_ = 0;
+ count_to_fill_ = 8;
+ bool_range_ = 255;
+ 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.
+ if (ReadLiteral(1) != 0) {
+ DVLOG(1) << "marker bit should be 0";
+ valid_ = false;
+ return false;
+ }
+ return true;
+}
+
+// Fill at least |count_to_fill_| bits and prefill remain bits of |bool_value_|
+// if data is enough.
+void Vp9BoolDecoder::Fill() {
+ DCHECK_GE(count_to_fill_, 0);
+
+ 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.
+ if (bits_left < count_to_fill_) {
+ valid_ = false;
+ DVLOG(1) << "Vp9BoolDecoder reads beyond the end of stream";
+ return;
+ }
+
+ DCHECK_LE(count_to_fill_, kBoolSize);
+ int max_bits_to_read = kBigBoolSize - kBoolSize + count_to_fill_;
+ int bits_to_read = std::min(max_bits_to_read, bits_left);
+
+ BigBool data;
+ reader_->ReadBits(bits_to_read, &data);
+ bool_value_ |= data << (max_bits_to_read - bits_to_read);
+ count_to_fill_ -= bits_to_read;
+}
+
+// 9.2.2 Boolean decoding process
+bool Vp9BoolDecoder::ReadBool(int prob) {
+ DCHECK(reader_);
+ 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
+ return false;
+
+ if (count_to_fill_ > 0) {
+ Fill();
+ 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.
+ return false;
+ }
+
+ 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
+ BigBool big_split = static_cast<BigBool>(split) << (kBigBoolSize - kBoolSize);
+
+ bool bit;
+ if (bool_value_ < big_split) {
+ bool_range_ = split;
+ bit = false;
+ } else {
+ bool_range_ -= split;
+ bool_value_ -= big_split;
+ bit = true;
+ }
+
+ // Need to fill |count| bits next time in order to make |bool_range_| >=
+ // 128.
+ DCHECK_LT(bool_range_, arraysize(kCountToShiftTo128));
+ DCHECK_GT(bool_range_, 0u);
+ int count = kCountToShiftTo128[bool_range_];
+ bool_range_ <<= count;
+ bool_value_ <<= count;
+ count_to_fill_ += count;
+
+ return bit;
+}
+
+// 9.2.4 Parsing process for read_literal
+int Vp9BoolDecoder::ReadLiteral(int bits) {
+ DCHECK(reader_);
+ if (!valid_)
+ return 0;
+
+ 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
+ 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.
+ x = 2 * x + ReadBool(128);
+
+ return x;
+}
+
+bool Vp9BoolDecoder::ConsumePaddingBits() {
+ DCHECK(reader_);
+ int data;
+
+ if (count_to_fill_ > reader_->bits_available()) {
+ // 9.2.2 Boolean decoding process
+ // Although we actually don't used the value, spec says the bitstream
+ // 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.
+ DVLOG(2) << "not enough bits in bitstream to fill bool range";
+ return false;
+ }
+
+ if (bool_value_ != 0) {
+ DVLOG(1) << "prefilled padding bits are not zero";
+ return false;
+ }
+ while (reader_->bits_available() > 0) {
+ int size_to_read =
+ std::min(reader_->bits_available(), static_cast<int>(sizeof(data) * 8));
+ reader_->ReadBits(size_to_read, &data);
+ if (data != 0) {
+ DVLOG(1) << "padding bits are not zero";
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698