LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/common_video/h264 - pps_parser.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 74 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2016 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             : 
      11             : #include "webrtc/common_video/h264/pps_parser.h"
      12             : 
      13             : #include <memory>
      14             : 
      15             : #include "webrtc/common_video/h264/h264_common.h"
      16             : #include "webrtc/base/bitbuffer.h"
      17             : #include "webrtc/base/buffer.h"
      18             : #include "webrtc/base/logging.h"
      19             : 
      20             : #define RETURN_EMPTY_ON_FAIL(x)                  \
      21             :   if (!(x)) {                                    \
      22             :     return rtc::Optional<PpsParser::PpsState>(); \
      23             :   }
      24             : 
      25             : namespace {
      26             : const int kMaxPicInitQpDeltaValue = 25;
      27             : const int kMinPicInitQpDeltaValue = -26;
      28             : }
      29             : 
      30             : namespace webrtc {
      31             : 
      32             : // General note: this is based off the 02/2014 version of the H.264 standard.
      33             : // You can find it on this page:
      34             : // http://www.itu.int/rec/T-REC-H.264
      35             : 
      36           0 : rtc::Optional<PpsParser::PpsState> PpsParser::ParsePps(const uint8_t* data,
      37             :                                                        size_t length) {
      38             :   // First, parse out rbsp, which is basically the source buffer minus emulation
      39             :   // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
      40             :   // section 7.3.1 of the H.264 standard.
      41           0 :   std::unique_ptr<rtc::Buffer> unpacked_buffer = H264::ParseRbsp(data, length);
      42           0 :   rtc::BitBuffer bit_buffer(unpacked_buffer->data(), unpacked_buffer->size());
      43           0 :   return ParseInternal(&bit_buffer);
      44             : }
      45             : 
      46           0 : bool PpsParser::ParsePpsIds(const uint8_t* data,
      47             :                             size_t length,
      48             :                             uint32_t* pps_id,
      49             :                             uint32_t* sps_id) {
      50           0 :   RTC_DCHECK(pps_id);
      51           0 :   RTC_DCHECK(sps_id);
      52             :   // First, parse out rbsp, which is basically the source buffer minus emulation
      53             :   // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
      54             :   // section 7.3.1 of the H.264 standard.
      55           0 :   std::unique_ptr<rtc::Buffer> unpacked_buffer = H264::ParseRbsp(data, length);
      56           0 :   rtc::BitBuffer bit_buffer(unpacked_buffer->data(), unpacked_buffer->size());
      57           0 :   return ParsePpsIdsInternal(&bit_buffer, pps_id, sps_id);
      58             : }
      59             : 
      60           0 : rtc::Optional<uint32_t> PpsParser::ParsePpsIdFromSlice(const uint8_t* data,
      61             :                                                        size_t length) {
      62           0 :   std::unique_ptr<rtc::Buffer> slice_rbsp(H264::ParseRbsp(data, length));
      63           0 :   rtc::BitBuffer slice_reader(slice_rbsp->data(), slice_rbsp->size());
      64             : 
      65             :   uint32_t golomb_tmp;
      66             :   // first_mb_in_slice: ue(v)
      67           0 :   if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
      68           0 :     return rtc::Optional<uint32_t>();
      69             :   // slice_type: ue(v)
      70           0 :   if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
      71           0 :     return rtc::Optional<uint32_t>();
      72             :   // pic_parameter_set_id: ue(v)
      73             :   uint32_t slice_pps_id;
      74           0 :   if (!slice_reader.ReadExponentialGolomb(&slice_pps_id))
      75           0 :     return rtc::Optional<uint32_t>();
      76           0 :   return rtc::Optional<uint32_t>(slice_pps_id);
      77             : }
      78             : 
      79           0 : rtc::Optional<PpsParser::PpsState> PpsParser::ParseInternal(
      80             :     rtc::BitBuffer* bit_buffer) {
      81           0 :   PpsState pps;
      82             : 
      83           0 :   RETURN_EMPTY_ON_FAIL(ParsePpsIdsInternal(bit_buffer, &pps.id, &pps.sps_id));
      84             : 
      85             :   uint32_t bits_tmp;
      86             :   uint32_t golomb_ignored;
      87             :   // entropy_coding_mode_flag: u(1)
      88             :   uint32_t entropy_coding_mode_flag;
      89           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&entropy_coding_mode_flag, 1));
      90           0 :   pps.entropy_coding_mode_flag = entropy_coding_mode_flag != 0;
      91             :   // bottom_field_pic_order_in_frame_present_flag: u(1)
      92             :   uint32_t bottom_field_pic_order_in_frame_present_flag;
      93           0 :   RETURN_EMPTY_ON_FAIL(
      94             :       bit_buffer->ReadBits(&bottom_field_pic_order_in_frame_present_flag, 1));
      95           0 :   pps.bottom_field_pic_order_in_frame_present_flag =
      96           0 :       bottom_field_pic_order_in_frame_present_flag != 0;
      97             : 
      98             :   // num_slice_groups_minus1: ue(v)
      99             :   uint32_t num_slice_groups_minus1;
     100           0 :   RETURN_EMPTY_ON_FAIL(
     101             :       bit_buffer->ReadExponentialGolomb(&num_slice_groups_minus1));
     102           0 :   if (num_slice_groups_minus1 > 0) {
     103             :     uint32_t slice_group_map_type;
     104             :     // slice_group_map_type: ue(v)
     105           0 :     RETURN_EMPTY_ON_FAIL(
     106             :         bit_buffer->ReadExponentialGolomb(&slice_group_map_type));
     107           0 :     if (slice_group_map_type == 0) {
     108           0 :       for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
     109             :            ++i_group) {
     110             :         // run_length_minus1[iGroup]: ue(v)
     111           0 :         RETURN_EMPTY_ON_FAIL(
     112             :             bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     113             :       }
     114           0 :     } else if (slice_group_map_type == 1) {
     115             :       // TODO(sprang): Implement support for dispersed slice group map type.
     116             :       // See 8.2.2.2 Specification for dispersed slice group map type.
     117           0 :     } else if (slice_group_map_type == 2) {
     118           0 :       for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
     119             :            ++i_group) {
     120             :         // top_left[iGroup]: ue(v)
     121           0 :         RETURN_EMPTY_ON_FAIL(
     122             :             bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     123             :         // bottom_right[iGroup]: ue(v)
     124           0 :         RETURN_EMPTY_ON_FAIL(
     125             :             bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     126             :       }
     127           0 :     } else if (slice_group_map_type == 3 || slice_group_map_type == 4 ||
     128           0 :                slice_group_map_type == 5) {
     129             :       // slice_group_change_direction_flag: u(1)
     130           0 :       RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&bits_tmp, 1));
     131             :       // slice_group_change_rate_minus1: ue(v)
     132           0 :       RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     133           0 :     } else if (slice_group_map_type == 6) {
     134             :       // pic_size_in_map_units_minus1: ue(v)
     135             :       uint32_t pic_size_in_map_units_minus1;
     136           0 :       RETURN_EMPTY_ON_FAIL(
     137             :           bit_buffer->ReadExponentialGolomb(&pic_size_in_map_units_minus1));
     138           0 :       uint32_t slice_group_id_bits = 0;
     139           0 :       uint32_t num_slice_groups = num_slice_groups_minus1 + 1;
     140             :       // If num_slice_groups is not a power of two an additional bit is required
     141             :       // to account for the ceil() of log2() below.
     142           0 :       if ((num_slice_groups & (num_slice_groups - 1)) != 0)
     143           0 :         ++slice_group_id_bits;
     144           0 :       while (num_slice_groups > 0) {
     145           0 :         num_slice_groups >>= 1;
     146           0 :         ++slice_group_id_bits;
     147             :       }
     148           0 :       for (uint32_t i = 0; i <= pic_size_in_map_units_minus1; i++) {
     149             :         // slice_group_id[i]: u(v)
     150             :         // Represented by ceil(log2(num_slice_groups_minus1 + 1)) bits.
     151           0 :         RETURN_EMPTY_ON_FAIL(
     152             :             bit_buffer->ReadBits(&bits_tmp, slice_group_id_bits));
     153             :       }
     154             :     }
     155             :   }
     156             :   // num_ref_idx_l0_default_active_minus1: ue(v)
     157           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     158             :   // num_ref_idx_l1_default_active_minus1: ue(v)
     159           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     160             :   // weighted_pred_flag: u(1)
     161             :   uint32_t weighted_pred_flag;
     162           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&weighted_pred_flag, 1));
     163           0 :   pps.weighted_pred_flag = weighted_pred_flag != 0;
     164             :   // weighted_bipred_idc: u(2)
     165           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&pps.weighted_bipred_idc, 2));
     166             : 
     167             :   // pic_init_qp_minus26: se(v)
     168           0 :   RETURN_EMPTY_ON_FAIL(
     169             :       bit_buffer->ReadSignedExponentialGolomb(&pps.pic_init_qp_minus26));
     170             :   // Sanity-check parsed value
     171           0 :   if (pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
     172           0 :       pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
     173           0 :     RETURN_EMPTY_ON_FAIL(false);
     174             :   }
     175             :   // pic_init_qs_minus26: se(v)
     176           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     177             :   // chroma_qp_index_offset: se(v)
     178           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
     179             :   // deblocking_filter_control_present_flag: u(1)
     180             :   // constrained_intra_pred_flag: u(1)
     181           0 :   RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&bits_tmp, 2));
     182             :   // redundant_pic_cnt_present_flag: u(1)
     183           0 :   RETURN_EMPTY_ON_FAIL(
     184             :       bit_buffer->ReadBits(&pps.redundant_pic_cnt_present_flag, 1));
     185             : 
     186           0 :   return rtc::Optional<PpsParser::PpsState>(pps);
     187             : }
     188             : 
     189           0 : bool PpsParser::ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer,
     190             :                                     uint32_t* pps_id,
     191             :                                     uint32_t* sps_id) {
     192             :   // pic_parameter_set_id: ue(v)
     193           0 :   if (!bit_buffer->ReadExponentialGolomb(pps_id))
     194           0 :     return false;
     195             :   // seq_parameter_set_id: ue(v)
     196           0 :   if (!bit_buffer->ReadExponentialGolomb(sps_id))
     197           0 :     return false;
     198           0 :   return true;
     199             : }
     200             : 
     201             : }  // namespace webrtc

Generated by: LCOV version 1.13