source: 3DVCSoftware/trunk/source/App/utils/BitrateTargeting/ExtractBitrates.cpp @ 872

Last change on this file since 872 was 872, checked in by tech, 10 years ago

Merged HTM-10.0-dev0@871. (MV-HEVC 7 HLS)

File size: 6.4 KB
Line 
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-2014, 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
41namespace
42{
43  /// Maintains a sum and a sample-count for calculating averages
44  class Tally
45  {
46    public:
47     
48      /// Contructs a new zeroed tally
49      Tally( ): m_sum( 0.0 ), m_numSlices( 0 ) { }
50     
51      /// Adds to the sum and increments the sample-count
52      void add( double in ) { ++m_numSlices; m_sum += in; }
53     
54      /// \return The calculated average
55      double average( ) const { return m_sum / ( double )m_numSlices; }
56   
57    private:
58      double m_sum;
59      unsigned long m_numSlices;
60  };
61 
62  /// Ignores all of the the characters up to and including a given character
63  /// \param line The line being read from
64  /// \param iLine The active input stream
65  /// \param character The character to ignore up to
66  /// \throw POCParseException if the stream goes bad before character is encountered or just after character is encountered
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( ) ) throw POCParseException( line );
72  }
73 
74  /// Extracts the average bitrates for each of the temporal layers from the given log
75  /// \param i The input stream that represents the log
76  /// \return A map that countains the average bitrates for each temporal layer.  Each pair contains the QP value in first and the average bitrate in second.
77  /// \throw POCParseException if an error occured while parsing a POC line
78  std::map< unsigned char, double > extractBitratesForQPs( std::istream& i )
79  {
80    std::map< unsigned char, Tally > tallyMap;
81   
82    while( i.good( ) )
83    {
84      // Initialize variables for this line
85      std::string line;
86      std::getline( i, line );
87      std::istringstream iLine( line );
88      if( !iLine.good( ) ) continue;
89     
90      // Ignore the "POC"
91      if( iLine.get( ) != 'P' ) continue;
92      if( !iLine.good( ) ) continue;
93      if( iLine.get( ) != 'O' ) continue;
94      if( !iLine.good( ) ) continue;
95      if( iLine.get( ) != 'C' ) continue;
96      if( !iLine.good( ) ) throw POCParseException( line );
97     
98      ignoreUpTo( line, iLine, '(' );
99     
100      if( iLine.get( ) != ' ' ) throw POCParseException( line );
101      if( !iLine.good( ) ) throw POCParseException( line );
102     
103      if( 'I' == iLine.get( ) ) continue;
104      if( !iLine.good( ) ) throw POCParseException( line );
105     
106      ignoreUpTo( line, iLine, ' ' );
107      ignoreUpTo( line, iLine, ' ' );
108     
109      // Parse the qpIndex
110      long qpIndexLong;
111      iLine >> qpIndexLong;
112      if( ( long )std::numeric_limits< unsigned char >::max( ) < qpIndexLong ) throw POCParseException( line );
113      unsigned char qpIndex( ( unsigned char )qpIndexLong );
114      if( !iLine.good( ) ) throw POCParseException( line );
115     
116      ignoreUpTo( line, iLine, ')' );
117      ignoreUpTo( line, iLine, ' ' );
118     
119      // Parse the number of bits
120      unsigned long bitsULong;
121      iLine >> bitsULong;
122      if( !iLine.good( ) ) throw POCParseException( line );
123     
124      // Find the tally that corresponds to our QP.  If there is no such tally yet, then add a new one to the map.
125      std::map< unsigned char, Tally >::iterator iter( tallyMap.find( qpIndex ) );
126      if( tallyMap.end( ) == iter )
127      {
128        tallyMap[ qpIndex ] = Tally( );
129        iter = tallyMap.find( qpIndex );
130      }
131      assert( iter != tallyMap.end( ) );
132     
133      iter->second.add( ( double )bitsULong );
134    }
135   
136    // Populate and return the result based on all of the tallies
137    std::map< unsigned char, double > result;
138    for( std::map< unsigned char, Tally >::const_iterator iter( tallyMap.begin( ) ); iter != tallyMap.end( ); ++iter )
139    {
140      result[ iter->first ] = iter->second.average( );
141    }
142    return result;
143  }
144}
145
146std::vector< double > extractBitratesForTemporalLayers( std::istream& i )
147{
148  std::vector< double > result;
149 
150  std::map< unsigned char, double > bitratesForQPsMap( extractBitratesForQPs( i ) );
151  if( !bitratesForQPsMap.empty( ) )
152  {
153    unsigned char expectedNextQPIndex( bitratesForQPsMap.begin( )->first );
154   
155    for( std::map< unsigned char, double >::const_iterator i( bitratesForQPsMap.begin( ) ); i != bitratesForQPsMap.end( ); ++i )
156    {
157      if( i->first != expectedNextQPIndex ) throw NonContiguousQPSetException( );
158      ++expectedNextQPIndex;
159      result.push_back( i->second );
160    }
161  }
162 
163  return result;
164}
Note: See TracBrowser for help on using the repository browser.