0

원시 Annex-B H.264 스트림의 압축을 푸는 코드를 작성하고 있습니다. 스트림 구문 분석, SPS/PPS NALUs에서 CMVideoFormatDescription 생성 및 CMSampleBuffers의 스트림에서 추출한 다른 NALUs.CMSampleBuffer의 CMBlockBuffer 소유권

디코더에 대한 CMBlockBuffer 및 CMSampleBuffer 메모리를 처리하는 방법에 대한 정신적 인 문제가 있습니다. 내 문제는 CF가 메모리를 어떻게 처리하는지에 대한 철저한 이해가 부족하기 때문에 내 질문은 그 이상입니다.하지만 문맥이 도움이되기를 바랍니다.

나는이 같은 CMBlockBuffer 만드는 경우 :

CMBlockBufferRef blockBuffer; 

OSStatus status = CMBlockBufferCreateWithMemoryBlock(NULL, 
                memoryBlock,      
                blockBufferLength, 
                kCFAllocatorNull, 
                NULL, 
                0, 
                blockBufferLength,   
                kCMBlockBufferAlwaysCopyDataFlag | kCMBlockBufferAssureMemoryNowFlag, 
                &blockBuffer); 

을이 같은 CMSampleBuffer에 추가 :

CMSampleBufferRef sampleBuffer; 

status = CMSampleBufferCreate(kCFAllocatorDefault, 
           blockBuffer, 
           true, 
           NULL, 
           NULL, 
           formatDescription, 
           1, 
           0, 
           NULL, 
           1, 
           &sampleSize, 
           &sampleBuffer); 

가 어떻게 블록 버퍼를 처리해야합니까? SampleBuffer는 블록 버퍼의 메모리를 유지합니까? 아니면 할당 해제되지 않았는지 확인하기 위해 무언가를해야합니까?

또한 비동기 디코드 프로세스와 관련하여 디코더가 CMSampleBuffer로 완료되면 알 수있는 합리적인 방법이 있습니까?

내 직감은 CMSampleBuffer가 CMBlockBuffer를 유지할 것이라고 말하고, VTDecodeSession은 디코딩이 완료 될 때까지 CMSampleBuffer를 유지하지만, 내가 배회하는 문서화되지 않은 영역이므로 방향을 찾고 있습니다. 내 직감을 함축하는 결과는 잘못되었을 수 있습니다. 따라서 메모리 관리를 문제없이 유지해야합니다 ...

답변

1

CMSampleBuffers 및 CMBlockBuffers - 일반적인 CF 유지/릴리스 의미를 따릅니다. 이러한 객체가 필요하면 유지를 유지해야하며 객체를 허용하는 인터페이스가 동일하다고 가정합니다. 즉, CMBlockBuffer를 CMSampleBuffer에 전달하자마자 CMBlockBuffer를 해제 할 수 있으며 렌더링 체인에 전달한 후 자유롭게 CMSampleBuffer를 해제 할 수 있습니다.

CMBlockBufferCreateWithMemoryBlock()으로 만든 CMBlockBuffer가 가리키는 메모리는 약간 다른 규칙을 따릅니다. 첫째,이 메서드는 memoryBlock이 가리키는 데이터를 복사하지 않습니다. 그 포인터를 직접 사용합니다. 즉, BlockBuffer는 메모리 관리 방법에 대한 지식이 필요합니다. 이것은 CMBlockBufferCreateWithMemoryBlock()에 대한 네 번째 또는 다섯 번째 인수에 의해 처리됩니다. 둘 중 하나가 kCFAllocatorNull/NULL이 아닌 경우 BlockBuffer는 메모리가 끝날 때 중 하나의 해제자를 호출합니다. 이것은 일반적으로 BlockBuffer의 Finalize()에서 수행됩니다. 둘 다 kCFAllocatorNull/NULL (코드 스 니펫에 있음) 인 경우 BlockBuffer는 메모리가 끝나면 포인터를 바닥에 놓습니다.

즉, CMBlockBufferCreateWithMemoryBlock()을 사용하여 CMBlockBuffer를 만들고 렌더링 파이프 라인을 통과 한 후 해당 BlockBuffer에 대한 retain을 해제하려는 경우 메모리가 할당 될 수 있도록 allocator/deallocator에 NULL이 아닌 인수를 사용해야합니다. 나중에 매립했다. 물론 이러한 할당 자/할당 취소 자의 구현은 memoryBlock의 출처에 따라 다릅니다.

+0

감사합니다. 도움이됩니다. 그래서 malloc을 사용하여 CMBlockBuffer를 할당한다면 올바른 할당 자의 값은 무엇입니까? –

+0

또 하나의 추가 노트가 있는데,이 작업이 가능해졌지만, VTDecompressionSessionCreate에 전달 된 다른 데이터 구조 인 CMVideoFormatDescription이 세션에서 복사되지 않는 것으로 나타났습니다. 추락해라. 이러한 조건의 충돌은 CFEqual 루틴의 어셈블리에 나타나며 한 레벨 위로 볼 경우 해당 시간에 CMVideoFormatDescription을 읽는 중입니다. –

+1

kCFAllocatorMalloc에 ​​대한 문서에서 malloc, realloc 및 free를 사용한다고 말합니다. 만약 내가 그 경로를 가야한다면 아마도 allocator의 free() 호출과 일치하는 malloc() 호출을 가정하기보다는 같은 할당자를 사용하여 메모리를 직접 할당 할 것입니다. 문서가 동일하다고 주장하더라도 더 안전하고 명확하고 이해하기 쉽습니다. – DSaracino