LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/video_coding/utility - vp8_header_parser.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 117 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : #include "webrtc/modules/video_coding/utility/vp8_header_parser.h"
      11             : 
      12             : #include "webrtc/base/logging.h"
      13             : 
      14             : namespace webrtc {
      15             : 
      16             : namespace vp8 {
      17             : namespace {
      18             : const size_t kCommonPayloadHeaderLength = 3;
      19             : const size_t kKeyPayloadHeaderLength = 10;
      20             : }  // namespace
      21             : 
      22           0 : static uint32_t BSwap32(uint32_t x) {
      23           0 :   return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
      24             : }
      25             : 
      26           0 : static void VP8LoadFinalBytes(VP8BitReader* const br) {
      27             :   // Only read 8bits at a time.
      28           0 :   if (br->buf_ < br->buf_end_) {
      29           0 :     br->bits_ += 8;
      30           0 :     br->value_ = static_cast<uint32_t>(*br->buf_++) | (br->value_ << 8);
      31           0 :   } else if (!br->eof_) {
      32           0 :     br->value_ <<= 8;
      33           0 :     br->bits_ += 8;
      34           0 :     br->eof_ = 1;
      35             :   }
      36           0 : }
      37             : 
      38           0 : static void VP8LoadNewBytes(VP8BitReader* const br) {
      39           0 :   int BITS = 24;
      40             :   // Read 'BITS' bits at a time.
      41           0 :   if (br->buf_ + sizeof(uint32_t) <= br->buf_end_) {
      42             :     uint32_t bits;
      43           0 :     const uint32_t in_bits = *(const uint32_t*)(br->buf_);
      44           0 :     br->buf_ += BITS >> 3;
      45             : #if defined(WEBRTC_ARCH_BIG_ENDIAN)
      46             :     bits = static_cast<uint32_t>(in_bits);
      47             :     if (BITS != 8 * sizeof(uint32_t))
      48             :       bits >>= (8 * sizeof(uint32_t) - BITS);
      49             : #else
      50           0 :     bits = BSwap32(in_bits);
      51           0 :     bits >>= 32 - BITS;
      52             : #endif
      53           0 :     br->value_ = bits | (br->value_ << BITS);
      54           0 :     br->bits_ += BITS;
      55             :   } else {
      56           0 :     VP8LoadFinalBytes(br);
      57             :   }
      58           0 : }
      59             : 
      60           0 : static void VP8InitBitReader(VP8BitReader* const br,
      61             :                              const uint8_t* const start,
      62             :                              const uint8_t* const end) {
      63           0 :   br->range_ = 255 - 1;
      64           0 :   br->buf_ = start;
      65           0 :   br->buf_end_ = end;
      66           0 :   br->value_ = 0;
      67           0 :   br->bits_ = -8;  // To load the very first 8bits.
      68           0 :   br->eof_ = 0;
      69           0 :   VP8LoadNewBytes(br);
      70           0 : }
      71             : 
      72             : // Read a bit with proba 'prob'.
      73           0 : static int VP8GetBit(VP8BitReader* const br, int prob) {
      74           0 :   uint8_t range = br->range_;
      75           0 :   if (br->bits_ < 0) {
      76           0 :     VP8LoadNewBytes(br);
      77           0 :     if (br->eof_)
      78           0 :       return 0;
      79             :   }
      80           0 :   const int pos = br->bits_;
      81           0 :   const uint8_t split = (range * prob) >> 8;
      82           0 :   const uint8_t value = static_cast<uint8_t>(br->value_ >> pos);
      83             :   int bit;
      84           0 :   if (value > split) {
      85           0 :     range -= split + 1;
      86           0 :     br->value_ -= static_cast<uint32_t>(split + 1) << pos;
      87           0 :     bit = 1;
      88             :   } else {
      89           0 :     range = split;
      90           0 :     bit = 0;
      91             :   }
      92           0 :   if (range <= static_cast<uint8_t>(0x7e)) {
      93           0 :     const int shift = kVP8Log2Range[range];
      94           0 :     range = kVP8NewRange[range];
      95           0 :     br->bits_ -= shift;
      96             :   }
      97           0 :   br->range_ = range;
      98           0 :   return bit;
      99             : }
     100             : 
     101           0 : static uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
     102           0 :   uint32_t v = 0;
     103           0 :   while (bits-- > 0) {
     104           0 :     v |= VP8GetBit(br, 0x80) << bits;
     105             :   }
     106           0 :   return v;
     107             : }
     108             : 
     109           0 : static uint32_t VP8Get(VP8BitReader* const br) {
     110           0 :   return VP8GetValue(br, 1);
     111             : }
     112             : 
     113           0 : static int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
     114           0 :   const int value = VP8GetValue(br, bits);
     115           0 :   return VP8Get(br) ? -value : value;
     116             : }
     117             : 
     118           0 : static void ParseSegmentHeader(VP8BitReader* br) {
     119           0 :   int use_segment = VP8Get(br);
     120           0 :   if (use_segment) {
     121           0 :     int update_map = VP8Get(br);
     122           0 :     if (VP8Get(br)) {
     123             :       int s;
     124           0 :       VP8Get(br);
     125           0 :       for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
     126           0 :         VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
     127             :       }
     128           0 :       for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
     129           0 :         VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
     130             :       }
     131             :     }
     132           0 :     if (update_map) {
     133             :       int s;
     134           0 :       for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
     135           0 :         VP8Get(br) ? VP8GetValue(br, 8) : 255;
     136             :       }
     137             :     }
     138             :   }
     139           0 : }
     140             : 
     141           0 : static void ParseFilterHeader(VP8BitReader* br) {
     142           0 :   VP8Get(br);
     143           0 :   VP8GetValue(br, 6);
     144           0 :   VP8GetValue(br, 3);
     145           0 :   int use_lf_delta = VP8Get(br);
     146           0 :   if (use_lf_delta) {
     147           0 :     if (VP8Get(br)) {
     148             :       int i;
     149           0 :       for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
     150           0 :         if (VP8Get(br)) {
     151           0 :           VP8GetSignedValue(br, 6);
     152             :         }
     153             :       }
     154           0 :       for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
     155           0 :         if (VP8Get(br)) {
     156           0 :           VP8GetSignedValue(br, 6);
     157             :         }
     158             :       }
     159             :     }
     160             :   }
     161           0 : }
     162             : 
     163           0 : bool GetQp(const uint8_t* buf, size_t length, int* qp) {
     164           0 :   if (length < kCommonPayloadHeaderLength) {
     165           0 :     LOG(LS_WARNING) << "Failed to get QP, invalid length.";
     166           0 :     return false;
     167             :   }
     168             :   VP8BitReader br;
     169           0 :   const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
     170           0 :   int key_frame = !(bits & 1);
     171             :   // Size of first partition in bytes.
     172           0 :   uint32_t partition_length = (bits >> 5);
     173           0 :   size_t header_length = kCommonPayloadHeaderLength;
     174           0 :   if (key_frame) {
     175           0 :     header_length = kKeyPayloadHeaderLength;
     176             :   }
     177           0 :   if (header_length + partition_length > length) {
     178           0 :     LOG(LS_WARNING) << "Failed to get QP, invalid length: " << length;
     179           0 :     return false;
     180             :   }
     181           0 :   buf += header_length;
     182             : 
     183           0 :   VP8InitBitReader(&br, buf, buf + partition_length);
     184           0 :   if (key_frame) {
     185             :     // Color space and pixel type.
     186           0 :     VP8Get(&br);
     187           0 :     VP8Get(&br);
     188             :   }
     189           0 :   ParseSegmentHeader(&br);
     190           0 :   ParseFilterHeader(&br);
     191             :   // Number of coefficient data partitions.
     192           0 :   VP8GetValue(&br, 2);
     193             :   // Base QP.
     194           0 :   const int base_q0 = VP8GetValue(&br, 7);
     195           0 :   if (br.eof_ == 1) {
     196           0 :     LOG(LS_WARNING) << "Failed to get QP, end of file reached.";
     197           0 :     return false;
     198             :   }
     199           0 :   *qp = base_q0;
     200           0 :   return true;
     201             : }
     202             : 
     203             : }  // namespace vp8
     204             : 
     205             : }  // namespace webrtc

Generated by: LCOV version 1.13