Changeset 1313 in 3DVCSoftware for trunk/source/App/utils/BitrateTargeting/GuessLambdaModifiers.cpp
- Timestamp:
- 13 Aug 2015, 17:38:13 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/App/utils/BitrateTargeting/GuessLambdaModifiers.cpp
r872 r1313 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 4 * granted under this license. 5 5 * 6 * Copyright (c) 2010-201 4, ITU/ISO/IEC6 * Copyright (c) 2010-2015, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 46 46 { 47 47 assert( right.empty( ) ); 48 48 49 49 for( ; ; ) 50 50 { 51 51 assert( left.good( ) ); 52 52 53 53 double bitrate; 54 54 left >> bitrate; 55 if( left.fail( ) ) break; 55 if( left.fail( ) ) 56 { 57 break; 58 } 56 59 if( bitrate <= ( double )0.0 ) 57 60 { … … 62 65 right.push_back( bitrate ); 63 66 } 64 if( !left.good( ) ) break; 65 67 if( !left.good( ) ) 68 { 69 break; 70 } 71 66 72 if( left.peek( ) == ' ' ) 67 73 { … … 74 80 } 75 81 } 76 82 77 83 /// Makes a next guess for a single Lambda-modifier based on only one previous guess 78 84 /// \param initialAdjustmentParameter The proportionality to use between the target bitrate and the previous guess … … 88 94 assert( ( double )0.0 < previousPoint.lambdaModifier ); 89 95 assert( ( double )0.0 < previousPoint.bitrate ); 90 96 91 97 double extrapolated( previousPoint.lambdaModifier * targetBitrate / previousPoint.bitrate ); 92 98 return previousPoint.lambdaModifier + initialAdjustmentParameter * ( extrapolated - previousPoint.lambdaModifier ); … … 102 108 assert( point1.lambdaModifier != point2.lambdaModifier ); 103 109 assert( point1.bitrate != point2.bitrate ); 104 110 105 111 // Calculate and return the result 106 112 double denominator( point1.bitrate - point2.bitrate ); … … 119 125 assert( interDampeningFactor <= ( double )1.0 ); 120 126 assert( !pointList.empty( ) ); 121 127 122 128 double preliminaryResult; 123 129 124 130 if( 1 == pointList.size( ) ) // If there is only one prevous point, then we cannot interpolate, so we call incrementLambdaModifier 125 131 { … … 132 138 ++i; 133 139 Point point2 = *i; 134 140 135 141 // If the slope is either horizontal or vertical, we cannot interpolate 136 142 if( point1.lambdaModifier == point2.lambdaModifier || point1.bitrate == point2.bitrate ) … … 143 149 } 144 150 } 145 151 146 152 double previousResult( pointList.back( ).lambdaModifier ); 147 153 148 154 // Apply "intra dampening" 149 155 { … … 159 165 } 160 166 } 161 167 162 168 // Apply "inter dampening factor". If necessary, reduce the factor until a positive result is acheived. 163 169 double result; … … 180 186 return result; 181 187 } 182 188 183 189 /// Calculates the inter dampening factor based 184 190 /// \param parameter The inter dampening parameter which determines how severely the inter dampening factor is affected by Lambda-modifier changes at previous temporal layers … … 202 208 assert( !targetBitrateVector.empty( ) ); 203 209 assert( !metaLogEntryList.empty( ) ); 204 210 205 211 double cumulativeDelta( 0.0 ); 206 212 std::vector< double > resultVector; … … 212 218 pointList.push_front( pointFromFullMetaLogEntry( i, *j ) ); 213 219 ++j; 214 if( j != metaLogEntryList.rend( ) ) pointList.push_front( pointFromFullMetaLogEntry( i, *j ) ); 215 220 if( j != metaLogEntryList.rend( ) ) 221 { 222 pointList.push_front( pointFromFullMetaLogEntry( i, *j ) ); 223 } 224 216 225 // Calculate the new Lambda-modifier guess and add it to the result vector 217 226 const double newLambdaModifier( guessLambdaModifier( … … 221 230 interDampeningFactor( 50.0, cumulativeDelta ) ) ); 222 231 resultVector.push_back( newLambdaModifier ); 223 232 224 233 // Increment the cumulativeDelta 225 234 const double oldLambdaModifier( pointList.back( ).lambdaModifier ); 226 235 cumulativeDelta += std::abs( newLambdaModifier - oldLambdaModifier ) / oldLambdaModifier; 227 236 } 228 237 229 238 return resultVector; 230 239 } … … 240 249 while( i.good( ) && character != i.get( ) ) 241 250 ; 242 if( !i.good( ) ) throw MetaLogParseException( ); 243 } 244 251 if( !i.good( ) ) 252 { 253 throw MetaLogParseException( ); 254 } 255 } 256 245 257 /// Parses a Lambda-modifier map 246 258 /// \param right The map to write the output to … … 250 262 { 251 263 assert( left.good( ) ); 252 264 253 265 // Ignore the "-LM" 254 if( '-' != left.get( ) ) left.setstate( std::istream::failbit ); 255 if( !left.good( ) ) break; 256 if( 'L' != left.get( ) ) left.setstate( std::istream::failbit ); 257 if( !left.good( ) ) break; 258 if( 'M' != left.get( ) ) left.setstate( std::istream::failbit ); 259 if( !left.good( ) ) break; 260 266 if( '-' != left.get( ) ) 267 { 268 left.setstate( std::istream::failbit ); 269 } 270 if( !left.good( ) ) 271 { 272 break; 273 } 274 if( 'L' != left.get( ) ) 275 { 276 left.setstate( std::istream::failbit ); 277 } 278 if( !left.good( ) ) 279 { 280 break; 281 } 282 if( 'M' != left.get( ) ) 283 { 284 left.setstate( std::istream::failbit ); 285 } 286 if( !left.good( ) ) 287 { 288 break; 289 } 290 261 291 // Parse the index 262 292 long indexLong; 263 293 left >> indexLong; 264 if( !left.good( ) ) break; 265 if( indexLong < std::numeric_limits< unsigned char >::min( ) ) left.setstate( std::istream::failbit ); 266 if( std::numeric_limits< unsigned char >::max( ) < indexLong ) left.setstate( std::istream::failbit ); 267 if( !left.good( ) ) break; 294 if( !left.good( ) ) 295 { 296 break; 297 } 298 if( indexLong < std::numeric_limits< unsigned char >::min( ) ) 299 { 300 left.setstate( std::istream::failbit ); 301 } 302 if( std::numeric_limits< unsigned char >::max( ) < indexLong ) 303 { 304 left.setstate( std::istream::failbit ); 305 } 306 if( !left.good( ) ) 307 { 308 break; 309 } 268 310 unsigned char index( ( unsigned char )indexLong ); 269 270 if( ' ' != left.get( ) ) left.setstate( std::istream::failbit ); 271 if( !left.good( ) ) break; 272 311 312 if( ' ' != left.get( ) ) 313 { 314 left.setstate( std::istream::failbit ); 315 } 316 if( !left.good( ) ) 317 { 318 break; 319 } 320 273 321 // Parse the Lambda-modifier 274 322 double lambdaModifier; … … 282 330 right[ index ] = lambdaModifier; 283 331 } 284 if( !left.good( ) ) break; 285 332 if( !left.good( ) ) 333 { 334 break; 335 } 336 286 337 // If we peek and see a space, then there should be more Lambda-modifiers to parse. Otherwise, we are finished. 287 338 if( left.peek( ) == ' ' ) … … 295 346 } 296 347 } 297 348 298 349 /// Extracts the indexes from the given maps 299 350 /// \return The set of indexes … … 322 373 throw InitialAdjustmentParameterParseException( ); 323 374 } 324 375 325 376 // Parse the targets 326 377 std::vector< double > targetVector; 327 378 parseBitrateVector( targetsIstream, targetVector ); 328 if( targetVector.empty( ) || targetsIstream.fail( ) || targetsIstream.good( ) ) throw TargetsParseException( ); 329 379 if( targetVector.empty( ) || targetsIstream.fail( ) || targetsIstream.good( ) ) 380 { 381 throw TargetsParseException( ); 382 } 383 330 384 // Parse the metalog 331 385 std::list< MetaLogEntry< std::map< unsigned char, double > > > metaLogEntryList; … … 335 389 MetaLogEntry< std::map< unsigned char, double > > entry; 336 390 parseLambdaModifierMap( metaLogIstream, entry.lambdaModifiers ); 337 if( !metaLogIstream.good( ) ) throw MetaLogParseException( ); 338 391 if( !metaLogIstream.good( ) ) 392 { 393 throw MetaLogParseException( ); 394 } 395 339 396 // Skip the ';' 340 if( ';' != metaLogIstream.get( ) ) throw MetaLogParseException( ); 341 if( !metaLogIstream.good( ) ) throw MetaLogParseException( ); 342 397 if( ';' != metaLogIstream.get( ) ) 398 { 399 throw MetaLogParseException( ); 400 } 401 if( !metaLogIstream.good( ) ) 402 { 403 throw MetaLogParseException( ); 404 } 405 343 406 // Parse the bitrates 344 407 parseBitrateVector( metaLogIstream, entry.bitrateVector ); 345 if( metaLogIstream.fail( ) ) throw MetaLogParseException( ); 408 if( metaLogIstream.fail( ) ) 409 { 410 throw MetaLogParseException( ); 411 } 346 412 metaLogEntryList.push_back( entry ); 347 348 if( !metaLogIstream.good( ) ) break; 349 if( metaLogIstream.get( ) != '\n' ) throw MetaLogParseException( ); 413 414 if( !metaLogIstream.good( ) ) 415 { 416 break; 417 } 418 if( metaLogIstream.get( ) != '\n' ) 419 { 420 throw MetaLogParseException( ); 421 } 350 422 metaLogIstream.peek( ); 351 423 } while( metaLogIstream.good( ) ); 352 if( metaLogEntryList.empty( ) ) throw MetaLogParseException( ); // The meta-log should not be empty 353 424 if( metaLogEntryList.empty( ) ) 425 { 426 throw MetaLogParseException( ); // The meta-log should not be empty 427 } 428 354 429 // Initialize firstIndexVector and check that the sizes and indexes match 355 430 std::set< unsigned char > firstIndexSet( indexSetFromMap( metaLogEntryList.front( ).lambdaModifiers ) ); 356 if( firstIndexSet.size( ) != targetVector.size( ) ) throw MismatchedIndexesException( ); 431 if( firstIndexSet.size( ) != targetVector.size( ) ) 432 { 433 throw MismatchedIndexesException( ); 434 } 357 435 for( std::list< MetaLogEntry< std::map< unsigned char, double > > >::const_iterator i( metaLogEntryList.begin( ) ); 358 436 i != metaLogEntryList.end( ); 359 437 ++i ) 360 438 { 361 if( indexSetFromMap( i->lambdaModifiers ) != firstIndexSet ) throw MismatchedIndexesException( ); 362 if( i->bitrateVector.size( ) != targetVector.size( ) ) throw MismatchedIndexesException( ); 363 } 364 439 if( indexSetFromMap( i->lambdaModifiers ) != firstIndexSet ) 440 { 441 throw MismatchedIndexesException( ); 442 } 443 if( i->bitrateVector.size( ) != targetVector.size( ) ) 444 { 445 throw MismatchedIndexesException( ); 446 } 447 } 448 365 449 // Initialize simplifiedMetaLogEntryList 366 450 std::list< MetaLogEntry< std::vector< double > > > simplifiedMetaLogEntryList; … … 376 460 simplifiedMetaLogEntryList.back( ).bitrateVector = i->bitrateVector; 377 461 } 378 462 379 463 // Run the calculations 380 464 std::vector< double > resultVector( guessLambdaModifiers( initialAdjustmentParameter, targetVector, simplifiedMetaLogEntryList ) ); 381 465 382 466 // Output the results 383 467 std::set< unsigned char >::const_iterator indexIter( firstIndexSet.begin( ) ); … … 385 469 do 386 470 { 387 if( indexIter != firstIndexSet.begin( ) ) o << " "; 471 if( indexIter != firstIndexSet.begin( ) ) 472 { 473 o << " "; 474 } 388 475 o << "-LM" << ( long )( *indexIter ) << " "; 389 476 o.setf( std::ostream::fixed, std::ostream::floatfield ); 390 477 o.precision( 7 ); 391 478 o << ( *resultIter ); 392 479 393 480 ++indexIter; 394 481 ++resultIter;
Note: See TracChangeset for help on using the changeset viewer.