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