title: Get the width / height of the video from H.264 NALU
body: <p>I have gotten the SPS in NALU ( AVC Decoder Configuration Record ), and trying to parse the video width / height from it.</p>
  
  <pre><code>67 64 00 15 ac c8 60 20 09 6c 04 40 00 00 03 00 40 00 00 07 a3 c5 8b 67 80 
  </code></pre>
  
  <p>This is my code parse the SPS but gets the wrong values.
  pic_width_in_mbs_minus1 is 5, and pic_height_in_map_units_minus1 is 1.
  Actually the video is 512 X 288px</p>
  
  <pre><code>typedef struct _SequenceParameterSet
  {
  private:
      const unsigned char * m_pStart;
      unsigned short m_nLength;
      int m_nCurrentBit;
  
      unsigned int ReadBit()
      {
          ATLASSERT(m_nCurrentBit &lt;= m_nLength * 8);
          int nIndex = m_nCurrentBit / 8;
          int nOffset = m_nCurrentBit % 8 + 1;
  
          m_nCurrentBit ++;
          return (m_pStart[nIndex] &gt;&gt; (8-nOffset)) &amp; 0x01;
      }
  
      unsigned int ReadBits(int n)
      {
          int r = 0;
          int i;
          for (i = 0; i &lt; n; i++)
          {
              r |= ( ReadBit() &lt;&lt; ( n - i - 1 ) );
          }
          return r;
      }
  
      unsigned int ReadExponentialGolombCode()
      {
          int r = 0;
          int i = 0;
  
          while( (ReadBit() == 0) &amp;&amp; (i &lt; 32) )
          {
              i++;
          }
          r = ReadBits(i);
          r += (1 &lt;&lt; i) - 1;
          return r;
      }
  
  
      unsigned int ReadSE() 
      {
          int r = ReadExponentialGolombCode();
          if (r &amp; 0x01)
          {
              r = (r+1)/2;
          }
          else
          {
              r = -(r/2);
          }
          return r;
      }
  public:
  
      void Parse(const unsigned char * pStart, unsigned short nLen)
      {
          m_pStart = pStart;
          m_nLength = nLen;
          m_nCurrentBit = 0;
          int profile_idc = ReadBits(8);
          int constraint_set0_flag = ReadBit();
          int constraint_set1_flag = ReadBit();
          int constraint_set2_flag = ReadBit();
          int constraint_set3_flag = ReadBit();
          int constraint_set4_flag = ReadBit();
          int constraint_set5_flag = ReadBit();
          int reserved_zero_2bits  = ReadBits(2);
          int level_idc = ReadBits(8);
          int seq_parameter_set_id = ReadExponentialGolombCode();
  
          if( profile_idc == 100 || profile_idc == 110 ||
              profile_idc == 122 || profile_idc == 144 )
          {
              int chroma_format_idc = ReadExponentialGolombCode();
              if( chroma_format_idc == 3 )
              {
                  int residual_colour_transform_flag = ReadBit();
              }
              int bit_depth_luma_minus8 = ReadExponentialGolombCode();
              int bit_depth_chroma_minus8 = ReadExponentialGolombCode();
              int qpprime_y_zero_transform_bypass_flag = ReadBit();
              int seq_scaling_matrix_present_flag = ReadBit();
              if( seq_scaling_matrix_present_flag )
              {
                  for( int i = 0; i &lt; 8; i++ )
                  {
                      int seq_scaling_list_present_flag = ReadBit();
                      if( seq_scaling_list_present_flag )
                      {
                          /*
                          if( i &lt; 6 )
                          {
                              read_scaling_list( b, sps-&gt;ScalingList4x4[ i ], 16,
                                  sps-&gt;UseDefaultScalingMatrix4x4Flag[ i ]);
                          }
                          else
                          {
                              read_scaling_list( b, sps-&gt;ScalingList8x8[ i - 6 ], 64,
                                  sps-&gt;UseDefaultScalingMatrix8x8Flag[ i - 6 ] );
                          }
                          */
                      }
                  }
              }
          }
          int log2_max_frame_num_minus4 = ReadExponentialGolombCode();
          int pic_order_cnt_type = ReadExponentialGolombCode();
          if( pic_order_cnt_type == 0 )
          {
              int log2_max_pic_order_cnt_lsb_minus4 = ReadExponentialGolombCode();
          }
          else if( pic_order_cnt_type == 1 )
          {
              int delta_pic_order_always_zero_flag = ReadBit();
              int offset_for_non_ref_pic = ReadSE();
              int offset_for_top_to_bottom_field = ReadSE();
              int num_ref_frames_in_pic_order_cnt_cycle = ReadExponentialGolombCode();
              for( int i = 0; i &lt; num_ref_frames_in_pic_order_cnt_cycle; i++ )
              {
                  ReadSE();
                  //sps-&gt;offset_for_ref_frame[ i ] = ReadSE();
              }
          }
          int num_ref_frames = ReadExponentialGolombCode();
          int gaps_in_frame_num_value_allowed_flag = ReadBit();
          int pic_width_in_mbs_minus1 = ReadExponentialGolombCode();
          int pic_height_in_map_units_minus1 = ReadExponentialGolombCode();
          int frame_mbs_only_flag = ReadBit();
          if( !frame_mbs_only_flag )
          {
              int mb_adaptive_frame_field_flag = ReadBit();
          }
          int direct_8x8_inference_flag = ReadBit();
          int frame_cropping_flag = ReadBit();
          if( frame_cropping_flag )
          {
              int frame_crop_left_offset = ReadExponentialGolombCode();
              int frame_crop_right_offset = ReadExponentialGolombCode();
              int frame_crop_top_offset = ReadExponentialGolombCode();
              int frame_crop_bottom_offset = ReadExponentialGolombCode();
          }
          int vui_parameters_present_flag = ReadBit();
  
          pStart++;
      }
  }SequenceParameterSet, *LPSequenceParameterSet;
  </code></pre>
  
  <p>This is my code parse the SPS but gets the wrong values. pic_width_in_mbs_minus1 is 5, and pic_height_in_map_units_minus1 is 1. Actually the video is 512 X 288px</p>
  
  <p>Thanks </p>