123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // 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 <algorithm>
- #include <memory>
- #include "base/logging.h"
- #include "media/base/bit_reader.h"
- namespace media {
- namespace {
- // This is an optimization lookup table for the loop in spec 9.2.2.
- // while BoolRange <= 128:
- // read 1 bit
- // BoolRange *= 2
- // This table indicates how many iterations to run for a given BoolRange. So
- // the loop could be reduced to
- // read (kCountToShiftTo128[BoolRange]) bits
- const int kCountToShiftTo128[256] = {
- 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() = default;
- Vp9BoolDecoder::~Vp9BoolDecoder() = default;
- // 9.2.1 Initialization process for Boolean decoder
- bool Vp9BoolDecoder::Initialize(const uint8_t* data, size_t size) {
- DCHECK(data);
- if (size < 1) {
- DVLOG(1) << "input size of bool decoder shall be at least 1";
- valid_ = false;
- return false;
- }
- reader_ = std::make_unique<BitReader>(data, size);
- valid_ = true;
- bool_value_ = 0;
- count_to_fill_ = 8;
- bool_range_ = 255;
- 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.
- bool Vp9BoolDecoder::Fill() {
- DCHECK_GE(count_to_fill_, 0);
- int bits_left = reader_->bits_available();
- if (bits_left < count_to_fill_) {
- valid_ = false;
- DVLOG(1) << "Vp9BoolDecoder reads beyond the end of stream";
- return false;
- }
- DCHECK_LE(count_to_fill_, kBoolSize);
- int max_bits_to_read = kBigBoolBitSize - 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;
- return true;
- }
- // 9.2.2 Boolean decoding process
- bool Vp9BoolDecoder::ReadBool(int prob) {
- DCHECK(reader_);
- if (count_to_fill_ > 0) {
- if (!Fill())
- return false;
- }
- unsigned int split = (bool_range_ * prob + (256 - prob)) >> kBoolSize;
- BigBool big_split = static_cast<BigBool>(split)
- << (kBigBoolBitSize - 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_, std::size(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
- uint8_t Vp9BoolDecoder::ReadLiteral(int bits) {
- DCHECK_LT(static_cast<size_t>(bits), sizeof(uint8_t) * 8);
- DCHECK(reader_);
- uint8_t x = 0;
- for (int i = 0; i < bits; i++)
- x = 2 * x + ReadBool(128);
- return x;
- }
- bool Vp9BoolDecoder::ConsumePaddingBits() {
- DCHECK(reader_);
- 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 happen.
- 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 data;
- 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
|