1c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// Copyright 2016 The Chromium Authors. All rights reserved. 2c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// Use of this source code is governed by a BSD-style license that can be 3c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// found in the LICENSE file. 4a21d5d577bdc284457867409e2a9c3b4a665d152Johny Lin// Note: ported from Chromium commit head: 1323b9c 5c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 6c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin#include "vp9_bool_decoder.h" 7c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 8c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin#include <algorithm> 9c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 10c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin#include "base/logging.h" 11c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin#include "bit_reader.h" 12c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 13c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linnamespace media { 14c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 15c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linnamespace { 16c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 17c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// This is an optimization lookup table for the loop in spec 9.2.2. 18c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// while BoolRange <= 128: 19c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// read 1 bit 20c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// BoolRange *= 2 21c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// This table indicates how many iterations to run for a given BoolRange. So 22c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// the loop could be reduced to 23c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// read (kCountToShiftTo128[BoolRange]) bits 24c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linconst int kCountToShiftTo128[256] = { 25c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 26c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 27c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 28c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 30c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin}; 37c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} // namespace 38c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 39a21d5d577bdc284457867409e2a9c3b4a665d152Johny LinVp9BoolDecoder::Vp9BoolDecoder() = default; 40c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 41a21d5d577bdc284457867409e2a9c3b4a665d152Johny LinVp9BoolDecoder::~Vp9BoolDecoder() = default; 42c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 43c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// 9.2.1 Initialization process for Boolean decoder 44c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linbool Vp9BoolDecoder::Initialize(const uint8_t* data, size_t size) { 45c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK(data); 46c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (size < 1) { 47c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(1) << "input size of bool decoder shall be at least 1"; 48c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin valid_ = false; 49c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 50c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 51c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 52c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin reader_.reset(new BitReader(data, size)); 53c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin valid_ = true; 54c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 55c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_value_ = 0; 56c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin count_to_fill_ = 8; 57c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_range_ = 255; 58c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (ReadLiteral(1) != 0) { 59c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(1) << "marker bit should be 0"; 60c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin valid_ = false; 61c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 62c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 63c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return true; 64c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} 65c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 66c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// Fill at least |count_to_fill_| bits and prefill remain bits of |bool_value_| 67c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// if data is enough. 68c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linbool Vp9BoolDecoder::Fill() { 69c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK_GE(count_to_fill_, 0); 70c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 71c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int bits_left = reader_->bits_available(); 72c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (bits_left < count_to_fill_) { 73c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin valid_ = false; 74c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(1) << "Vp9BoolDecoder reads beyond the end of stream"; 75c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 76c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 77c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 78c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK_LE(count_to_fill_, kBoolSize); 79c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int max_bits_to_read = kBigBoolBitSize - kBoolSize + count_to_fill_; 80c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int bits_to_read = std::min(max_bits_to_read, bits_left); 81c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 82c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin BigBool data; 83c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin reader_->ReadBits(bits_to_read, &data); 84c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_value_ |= data << (max_bits_to_read - bits_to_read); 85c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin count_to_fill_ -= bits_to_read; 86c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 87c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return true; 88c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} 89c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 90c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// 9.2.2 Boolean decoding process 91c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linbool Vp9BoolDecoder::ReadBool(int prob) { 92c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK(reader_); 93c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 94c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (count_to_fill_ > 0) { 95c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (!Fill()) 96c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 97c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 98c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 99c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin unsigned int split = (bool_range_ * prob + (256 - prob)) >> kBoolSize; 100c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin BigBool big_split = static_cast<BigBool>(split) 101c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin << (kBigBoolBitSize - kBoolSize); 102c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 103c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool bit; 104c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (bool_value_ < big_split) { 105c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_range_ = split; 106c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bit = false; 107c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } else { 108c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_range_ -= split; 109c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_value_ -= big_split; 110c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bit = true; 111c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 112c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 113c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin // Need to fill |count| bits next time in order to make |bool_range_| >= 114c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin // 128. 115c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK_LT(bool_range_, arraysize(kCountToShiftTo128)); 116c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK_GT(bool_range_, 0u); 117c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int count = kCountToShiftTo128[bool_range_]; 118c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_range_ <<= count; 119c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin bool_value_ <<= count; 120c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin count_to_fill_ += count; 121c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 122c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return bit; 123c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} 124c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 125c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin// 9.2.4 Parsing process for read_literal 126c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linuint8_t Vp9BoolDecoder::ReadLiteral(int bits) { 127c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK_LT(static_cast<size_t>(bits), sizeof(uint8_t) * 8); 128c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK(reader_); 129c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 130c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin uint8_t x = 0; 131c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin for (int i = 0; i < bits; i++) 132c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin x = 2 * x + ReadBool(128); 133c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 134c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return x; 135c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} 136c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 137c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Linbool Vp9BoolDecoder::ConsumePaddingBits() { 138c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DCHECK(reader_); 139c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 140c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (count_to_fill_ > reader_->bits_available()) { 141c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin // 9.2.2 Boolean decoding process 142c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin // Although we actually don't used the value, spec says the bitstream 143c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin // should have enough bits to fill bool range, this should never happen. 144c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(2) << "not enough bits in bitstream to fill bool range"; 145c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 146c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 147c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 148c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (bool_value_ != 0) { 149c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(1) << "prefilled padding bits are not zero"; 150c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 151c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 152c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin while (reader_->bits_available() > 0) { 153c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int data; 154c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin int size_to_read = 155c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin std::min(reader_->bits_available(), static_cast<int>(sizeof(data) * 8)); 156c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin reader_->ReadBits(size_to_read, &data); 157c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin if (data != 0) { 158c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin DVLOG(1) << "padding bits are not zero"; 159c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return false; 160c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 161c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin } 162c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin return true; 163c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} 164c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin 165c8ab179e7518f2da789ff936d8ee4def58e2160aPin-chih Lin} // namespace media 166