@@ -457,6 +457,17 @@ createPixelBufferAttributesDictionary( SInt32 width, SInt32 height,
457457 return err ;
458458}
459459
460+ // A worst-case estimate of bytes per frame
461+ static size_t estimateBytesPerFrame (HapCompressorGlobals glob )
462+ {
463+ size_t inputSize = roundUpToMultipleOf4 (glob -> width ) * roundUpToMultipleOf4 (glob -> height ) * 4 ;
464+ size_t formatConvertSize = inputSize ;
465+ size_t dxtSize = dxtBytesForDimensions (glob -> width , glob -> height , glob -> type );
466+ size_t outputSize = glob -> maxEncodedDataSize ;
467+ size_t encodeSize = sizeof (HapCodecCompressTask );
468+ return inputSize + formatConvertSize + dxtSize + outputSize + encodeSize ;
469+ }
470+
460471// Prepare to compress frames.
461472// Compressor should record session and sessionOptions for use in later calls.
462473// Compressor may modify imageDescription at this point.
@@ -476,7 +487,8 @@ Hap_CPrepareToCompressFrames(
476487 int pixelFormatCount ;
477488 Fixed gammaLevel ;
478489 long wantedDXTSize ;
479-
490+ int maxTasks ;
491+
480492 switch (glob -> type ) {
481493 case kHapCodecSubType :
482494 pixelFormatList [2 ] = kHapCVPixelFormat_RGB_DXT1 ;
@@ -577,8 +589,14 @@ Hap_CPrepareToCompressFrames(
577589 err = memFullErr ;
578590 goto bail ;
579591 }
592+
593+ // Only use half of addressable memory (we're 32-bit, so UINT32_MAX)
594+ maxTasks = (UINT32_MAX / 2 ) / estimateBytesPerFrame (glob );
595+ // hapCodecMaxTasks() returns any system or host restrictions
596+ if (maxTasks > hapCodecMaxTasks ())
597+ maxTasks = hapCodecMaxTasks ();
580598
581- glob -> taskGroup = HapCodecTasksCreateGroup (Background_Encode , hapCodecMaxTasks () );
599+ glob -> taskGroup = HapCodecTasksCreateGroup (Background_Encode , maxTasks );
582600
583601#ifdef DEBUG
584602 glob -> debugStartTime = CVGetCurrentHostTime ();
0 commit comments