HEVC Test Model (HM)  HM-16.3
ExtractBitrates.cpp
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2015, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "ExtractBitrates.h"
35 #include <string>
36 #include <sstream>
37 #include <cassert>
38 #include <limits>
39 #include <map>
40 
41 namespace
42 {
44  class Tally
45  {
46  public:
47 
49  Tally( ): m_sum( 0.0 ), m_numSlices( 0 ) { }
50 
52  void add( double in ) { ++m_numSlices; m_sum += in; }
53 
55  double average( ) const { return m_sum / ( double )m_numSlices; }
56 
57  private:
58  double m_sum;
59  unsigned long m_numSlices;
60  };
61 
67  void ignoreUpTo( const std::string& line, std::istream& iLine, char character )
68  {
69  while( iLine.good( ) && character != iLine.get( ) )
70  ;
71  if( !iLine.good( ) )
72  {
73  throw POCParseException( line );
74  }
75  }
76 
81  std::map< unsigned char, double > extractBitratesForQPs( std::istream& i )
82  {
83  std::map< unsigned char, Tally > tallyMap;
84 
85  while( i.good( ) )
86  {
87  // Initialize variables for this line
88  std::string line;
89  std::getline( i, line );
90  std::istringstream iLine( line );
91  if( !iLine.good( ) )
92  {
93  continue;
94  }
95 
96  // Ignore the "POC"
97  if( iLine.get( ) != 'P' )
98  {
99  continue;
100  }
101  if( !iLine.good( ) )
102  {
103  continue;
104  }
105  if( iLine.get( ) != 'O' )
106  {
107  continue;
108  }
109  if( !iLine.good( ) )
110  {
111  continue;
112  }
113  if( iLine.get( ) != 'C' )
114  {
115  continue;
116  }
117  if( !iLine.good( ) )
118  {
119  throw POCParseException( line );
120  }
121 
122  ignoreUpTo( line, iLine, '(' );
123 
124  if( iLine.get( ) != ' ' )
125  {
126  throw POCParseException( line );
127  }
128  if( !iLine.good( ) )
129  {
130  throw POCParseException( line );
131  }
132 
133  if( 'I' == iLine.get( ) )
134  {
135  continue;
136  }
137  if( !iLine.good( ) )
138  {
139  throw POCParseException( line );
140  }
141 
142  ignoreUpTo( line, iLine, ' ' );
143  ignoreUpTo( line, iLine, ' ' );
144 
145  // Parse the qpIndex
146  long qpIndexLong;
147  iLine >> qpIndexLong;
148  if( ( long )std::numeric_limits< unsigned char >::max( ) < qpIndexLong )
149  {
150  throw POCParseException( line );
151  }
152  unsigned char qpIndex( ( unsigned char )qpIndexLong );
153  if( !iLine.good( ) )
154  {
155  throw POCParseException( line );
156  }
157 
158  ignoreUpTo( line, iLine, ')' );
159  ignoreUpTo( line, iLine, ' ' );
160 
161  // Parse the number of bits
162  unsigned long bitsULong;
163  iLine >> bitsULong;
164  if( !iLine.good( ) )
165  {
166  throw POCParseException( line );
167  }
168 
169  // Find the tally that corresponds to our QP. If there is no such tally yet, then add a new one to the map.
170  std::map< unsigned char, Tally >::iterator iter( tallyMap.find( qpIndex ) );
171  if( tallyMap.end( ) == iter )
172  {
173  tallyMap[ qpIndex ] = Tally( );
174  iter = tallyMap.find( qpIndex );
175  }
176  assert( iter != tallyMap.end( ) );
177 
178  iter->second.add( ( double )bitsULong );
179  }
180 
181  // Populate and return the result based on all of the tallies
182  std::map< unsigned char, double > result;
183  for( std::map< unsigned char, Tally >::const_iterator iter( tallyMap.begin( ) ); iter != tallyMap.end( ); ++iter )
184  {
185  result[ iter->first ] = iter->second.average( );
186  }
187  return result;
188  }
189 }
190 
191 std::vector< double > extractBitratesForTemporalLayers( std::istream& i )
192 {
193  std::vector< double > result;
194 
195  std::map< unsigned char, double > bitratesForQPsMap( extractBitratesForQPs( i ) );
196  if( !bitratesForQPsMap.empty( ) )
197  {
198  unsigned char expectedNextQPIndex( bitratesForQPsMap.begin( )->first );
199 
200  for( std::map< unsigned char, double >::const_iterator i( bitratesForQPsMap.begin( ) ); i != bitratesForQPsMap.end( ); ++i )
201  {
202  if( i->first != expectedNextQPIndex )
203  {
205  }
206  ++expectedNextQPIndex;
207  result.push_back( i->second );
208  }
209  }
210 
211  return result;
212 }
An error occured while parsing a POC line from within a log file.
std::vector< double > extractBitratesForTemporalLayers(std::istream &i)
The QP set from the log file was not contiguous. The QP set must be contiguous to be able to convert ...