198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen/* 298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * 498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * Use of this source code is governed by a BSD-style license 598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * that can be found in the LICENSE file in the root of the source 698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * tree. An additional intellectual property rights grant can be found 798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * in the file PATENTS. All contributing project authors may 898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen * be found in the AUTHORS file in the root of the source tree. 998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen */ 10b7ce96470b99510937e489bcb4dc3165a9ab1b28kjellander@webrtc.org#include "webrtc/modules/video_coding/utility/vp8_header_parser.h" 1198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 12854e84c7fb61972bd8e39c1482e5f3e31f796b5fpbos#include "webrtc/base/logging.h" 1386b016027d2d27c62fedd108354a2b1274118ae3asapersson 1498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychennamespace webrtc { 1598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 1698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychennamespace vp8 { 1786b016027d2d27c62fedd108354a2b1274118ae3asaperssonnamespace { 1886b016027d2d27c62fedd108354a2b1274118ae3asaperssonconst size_t kCommonPayloadHeaderLength = 3; 1986b016027d2d27c62fedd108354a2b1274118ae3asaperssonconst size_t kKeyPayloadHeaderLength = 10; 2086b016027d2d27c62fedd108354a2b1274118ae3asapersson} // namespace 2198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 2298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic uint32_t BSwap32(uint32_t x) { 2398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); 2498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 2598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 2698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic void VP8LoadFinalBytes(VP8BitReader* const br) { 2798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Only read 8bits at a time. 2898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (br->buf_ < br->buf_end_) { 2998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->bits_ += 8; 3098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->value_ = static_cast<uint32_t>(*br->buf_++) | (br->value_ << 8); 3198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } else if (!br->eof_) { 3298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->value_ <<= 8; 3398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->bits_ += 8; 3498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->eof_ = 1; 3598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 3698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 3798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 3898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic void VP8LoadNewBytes(VP8BitReader* const br) { 3998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int BITS = 24; 4098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Read 'BITS' bits at a time. 4198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (br->buf_ + sizeof(uint32_t) <= br->buf_end_) { 4298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen uint32_t bits; 4398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint32_t in_bits = *(const uint32_t*)(br->buf_); 4498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->buf_ += BITS >> 3; 4598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen#if defined(WEBRTC_ARCH_BIG_ENDIAN) 465908c71128aea207e42f86468aedb0a6fce3cccbphilipel bits = static_cast<uint32_t>(in_bits); 475908c71128aea207e42f86468aedb0a6fce3cccbphilipel if (BITS != 8 * sizeof(uint32_t)) 485908c71128aea207e42f86468aedb0a6fce3cccbphilipel bits >>= (8 * sizeof(uint32_t) - BITS); 4998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen#else 505908c71128aea207e42f86468aedb0a6fce3cccbphilipel bits = BSwap32(in_bits); 515908c71128aea207e42f86468aedb0a6fce3cccbphilipel bits >>= 32 - BITS; 5298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen#endif 5398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->value_ = bits | (br->value_ << BITS); 5498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->bits_ += BITS; 5598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } else { 5698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8LoadFinalBytes(br); 5798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 5898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 5998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 6098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic void VP8InitBitReader(VP8BitReader* const br, 6198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint8_t* const start, 6298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint8_t* const end) { 635908c71128aea207e42f86468aedb0a6fce3cccbphilipel br->range_ = 255 - 1; 645908c71128aea207e42f86468aedb0a6fce3cccbphilipel br->buf_ = start; 6598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->buf_end_ = end; 665908c71128aea207e42f86468aedb0a6fce3cccbphilipel br->value_ = 0; 675908c71128aea207e42f86468aedb0a6fce3cccbphilipel br->bits_ = -8; // To load the very first 8bits. 685908c71128aea207e42f86468aedb0a6fce3cccbphilipel br->eof_ = 0; 6998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8LoadNewBytes(br); 7098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 7198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 7298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen// Read a bit with proba 'prob'. 7398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic int VP8GetBit(VP8BitReader* const br, int prob) { 7498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen uint8_t range = br->range_; 7598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (br->bits_ < 0) { 7698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8LoadNewBytes(br); 7798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 7898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 7998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const int pos = br->bits_; 8098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint8_t split = (range * prob) >> 8; 8198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint8_t value = static_cast<uint8_t>(br->value_ >> pos); 8298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int bit; 8398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (value > split) { 8498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen range -= split + 1; 8598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->value_ -= static_cast<uint32_t>(split + 1) << pos; 8698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen bit = 1; 8798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } else { 8898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen range = split; 8998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen bit = 0; 9098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 9198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (range <= static_cast<uint8_t>(0x7e)) { 9298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const int shift = kVP8Log2Range[range]; 9398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen range = kVP8NewRange[range]; 9498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->bits_ -= shift; 9598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 9698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen br->range_ = range; 9798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen return bit; 9898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 9998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 10098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic uint32_t VP8GetValue(VP8BitReader* const br, int bits) { 10198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen uint32_t v = 0; 10298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen while (bits-- > 0) { 10398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen v |= VP8GetBit(br, 0x80) << bits; 10498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 10598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen return v; 10698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 10798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 10898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic uint32_t VP8Get(VP8BitReader* const br) { 10998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen return VP8GetValue(br, 1); 11098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 11198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 11298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { 11398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const int value = VP8GetValue(br, bits); 11498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen return VP8Get(br) ? -value : value; 11598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 11698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 11798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic void ParseSegmentHeader(VP8BitReader* br) { 11898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int use_segment = VP8Get(br); 11998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (use_segment) { 12098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int update_map = VP8Get(br); 12198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (VP8Get(br)) { 12298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int s; 12398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(br); 12498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 1255908c71128aea207e42f86468aedb0a6fce3cccbphilipel VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; 12698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 12798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 12898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; 12998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 13098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 13198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (update_map) { 13298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int s; 13398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { 13498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(br) ? VP8GetValue(br, 8) : 255; 13598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 13698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 13798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 13898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 13998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 14098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychenstatic void ParseFilterHeader(VP8BitReader* br) { 14198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(br); 14298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8GetValue(br, 6); 14398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8GetValue(br, 3); 14498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int use_lf_delta = VP8Get(br); 14598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (use_lf_delta) { 14698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (VP8Get(br)) { 14798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int i; 14898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { 14998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (VP8Get(br)) { 15098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8GetSignedValue(br, 6); 15198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 15298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 15398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { 15498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (VP8Get(br)) { 15598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8GetSignedValue(br, 6); 15698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 15798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 15898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 15998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 16098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 16198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 16286b016027d2d27c62fedd108354a2b1274118ae3asaperssonbool GetQp(const uint8_t* buf, size_t length, int* qp) { 16386b016027d2d27c62fedd108354a2b1274118ae3asapersson if (length < kCommonPayloadHeaderLength) { 16486b016027d2d27c62fedd108354a2b1274118ae3asapersson LOG(LS_WARNING) << "Failed to get QP, invalid length."; 16586b016027d2d27c62fedd108354a2b1274118ae3asapersson return false; 16686b016027d2d27c62fedd108354a2b1274118ae3asapersson } 16798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8BitReader br; 16898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 16998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen int key_frame = !(bits & 1); 17098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Size of first partition in bytes. 17186b016027d2d27c62fedd108354a2b1274118ae3asapersson uint32_t partition_length = (bits >> 5); 17286b016027d2d27c62fedd108354a2b1274118ae3asapersson size_t header_length = kCommonPayloadHeaderLength; 17398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (key_frame) { 17486b016027d2d27c62fedd108354a2b1274118ae3asapersson header_length = kKeyPayloadHeaderLength; 17598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 17686b016027d2d27c62fedd108354a2b1274118ae3asapersson if (header_length + partition_length > length) { 17786b016027d2d27c62fedd108354a2b1274118ae3asapersson LOG(LS_WARNING) << "Failed to get QP, invalid length: " << length; 17886b016027d2d27c62fedd108354a2b1274118ae3asapersson return false; 17986b016027d2d27c62fedd108354a2b1274118ae3asapersson } 18086b016027d2d27c62fedd108354a2b1274118ae3asapersson buf += header_length; 18186b016027d2d27c62fedd108354a2b1274118ae3asapersson 18298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8InitBitReader(&br, buf, buf + partition_length); 18398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen if (key_frame) { 18498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Color space and pixel type. 18598d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(&br); 18698d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8Get(&br); 18798d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen } 18898d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen ParseSegmentHeader(&br); 18998d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen ParseFilterHeader(&br); 19098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Number of coefficient data partitions. 19198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen VP8GetValue(&br, 2); 19298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen // Base QP. 19398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen const int base_q0 = VP8GetValue(&br, 7); 19486b016027d2d27c62fedd108354a2b1274118ae3asapersson if (br.eof_ == 1) { 19586b016027d2d27c62fedd108354a2b1274118ae3asapersson LOG(LS_WARNING) << "Failed to get QP, end of file reached."; 19686b016027d2d27c62fedd108354a2b1274118ae3asapersson return false; 19786b016027d2d27c62fedd108354a2b1274118ae3asapersson } 19886b016027d2d27c62fedd108354a2b1274118ae3asapersson *qp = base_q0; 19986b016027d2d27c62fedd108354a2b1274118ae3asapersson return true; 20098d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} 20198d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 20298d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} // namespace vp8 20398d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen 20498d8cf58ee8c7c7b0672ce7955313a31824d6f3ajackychen} // namespace webrtc 205