Skip to content
This repository was archived by the owner on Oct 31, 2022. It is now read-only.

Commit 39f6911

Browse files
committed
Fix Windows background encoding
Don't call any QuickTime or CoreVideo functions from background threads
1 parent 50da7e1 commit 39f6911

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

source/HapCompressor.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ struct HapCodecCompressTask
130130
{
131131
HapCompressorGlobals glob;
132132
ICMCompressorSourceFrameRef sourceFrame;
133+
CVPixelBufferRef sourceFramePixelBuffer;
134+
const uint8_t *sourceFramePixelBufferBaseAddress;
133135
ICMMutableEncodedFrameRef encodedFrame;
136+
UInt8 *encodedFrameDataPtr;
134137
unsigned long encodedFrameActualSize;
135138
HapCodecBufferRef dxtBuffer;
136139
ComponentResult error;
@@ -636,7 +639,7 @@ static void Encode_Slice(void *p, unsigned int index)
636639
HapCodecEncodeDXTTask *task = (HapCodecEncodeDXTTask *)p;
637640

638641
unsigned int sliceHeight = task->sliceHeight;
639-
if ((index + 1) * sliceHeight > task->height)
642+
if ((index + 1) * sliceHeight > (unsigned int)task->height)
640643
sliceHeight = task->height - (index * sliceHeight);
641644

642645
const uint8_t *src = task->source + (index * task->sliceHeight * task->sourceBytesPerRow);
@@ -704,7 +707,6 @@ static void Background_Encode(void *info)
704707
{
705708
HapCodecCompressTask *task = (HapCodecCompressTask *)HapCodecBufferGetBaseAddress((HapCodecBufferRef)info);
706709
HapCompressorGlobals glob = task->glob;
707-
CVPixelBufferRef pixelBuffer = ICMCompressorSourceFrameGetPixelBuffer(task->sourceFrame);
708710

709711
const void *codec_src = NULL;
710712
unsigned int codec_src_length = 0;
@@ -720,21 +722,15 @@ static void Background_Encode(void *info)
720722
}
721723
else
722724
{
723-
if (CVPixelBufferLockBaseAddress(pixelBuffer, kHapCodecCVPixelBufferLockFlags) != kCVReturnSuccess)
724-
{
725-
err = internalComponentErr;
726-
goto bail;
727-
}
728-
729-
codec_src = CVPixelBufferGetBaseAddress(pixelBuffer);
725+
codec_src = task->sourceFramePixelBufferBaseAddress;
730726
codec_src_length = dxtBytesForDimensions(glob->width, glob->height, glob->type);
731727
}
732728

733729
hapResult = HapEncode(codec_src,
734730
codec_src_length,
735731
glob->dxtFormat,
736732
HapCompressorSnappy,
737-
ICMEncodedFrameGetDataPtr(task->encodedFrame),
733+
task->encodedFrameDataPtr,
738734
glob->maxEncodedDataSize,
739735
&(task->encodedFrameActualSize));
740736

@@ -761,15 +757,15 @@ static void Background_Encode(void *info)
761757
HapCodecBufferReturn(task->dxtBuffer);
762758
task->dxtBuffer = NULL;
763759
}
764-
765-
if (pixelBuffer)
766-
{
767-
CVPixelBufferUnlockBaseAddress(pixelBuffer, kHapCodecCVPixelBufferLockFlags);
768760
#if defined(__APPLE__)
761+
if (task->sourceFramePixelBuffer)
762+
{
763+
CVPixelBufferUnlockBaseAddress(task->sourceFramePixelBuffer, kHapCodecCVPixelBufferLockFlags);
769764
// Detach the pixel buffer so it can be recycled (not on Windows as QT isn't thread-safe there)
770765
ICMCompressorSourceFrameDetachPixelBuffer(task->sourceFrame);
771-
#endif
766+
task->sourceFramePixelBuffer = NULL;
772767
}
768+
#endif
773769

774770
task->error = err;
775771

@@ -1050,6 +1046,10 @@ static void disposeTask(HapCodecCompressTask *task)
10501046
{
10511047
if (task)
10521048
{
1049+
if (task->sourceFramePixelBuffer)
1050+
{
1051+
CVPixelBufferUnlockBaseAddress(task->sourceFramePixelBuffer, kHapCodecCVPixelBufferLockFlags);
1052+
}
10531053
ICMCompressorSourceFrameRelease(task->sourceFrame);
10541054
ICMEncodedFrameRelease(task->encodedFrame);
10551055
HapCodecBufferReturn(task->dxtBuffer);
@@ -1148,8 +1148,19 @@ static HapCodecBufferRef createTask(HapCompressorGlobals glob, HapCodecBufferRef
11481148
HapCodecCompressTask *task = (HapCodecCompressTask *)HapCodecBufferGetBaseAddress(buffer);
11491149

11501150
task->sourceFrame = ICMCompressorSourceFrameRetain(sourceFrame);
1151+
task->sourceFramePixelBuffer = ICMCompressorSourceFrameGetPixelBuffer(sourceFrame);
1152+
if (task->sourceFramePixelBuffer)
1153+
{
1154+
CVPixelBufferLockBaseAddress(task->sourceFramePixelBuffer, kHapCodecCVPixelBufferLockFlags);
1155+
task->sourceFramePixelBufferBaseAddress = CVPixelBufferGetBaseAddress(task->sourceFramePixelBuffer);
1156+
}
1157+
else
1158+
{
1159+
task->sourceFramePixelBufferBaseAddress = NULL;
1160+
}
11511161
task->glob = glob;
11521162
task->encodedFrame = (ICMMutableEncodedFrameRef)ICMEncodedFrameRetain(encodedFrame);
1163+
task->encodedFrameDataPtr = ICMEncodedFrameGetDataPtr(encodedFrame);
11531164
task->error = noErr;
11541165
task->next = NULL;
11551166
task->dxtBuffer = dxtBuffer;

0 commit comments

Comments
 (0)