title: CMSampleBufferRef pool to write H.264 AVCC stream
body: <p>I'm using AVAssetWriter/AVAssetWriterInput to write H.264 raw data to an MP4 file. As I'm receiving the data from a remote server, I use the following CoreMedia APIs to get a sample buffer (CMSampleBufferRef) containing the H.264 data in AVCC format that is in turned appended to an MP4 file by sending to an <code>AVAssetWriterInput</code> the message <code>(BOOL)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer</code>:</p>
  
  <blockquote>
    <ol>
    <li><code>CMBlockBufferCreateWithMemoryBlock</code> to create a memory block</li>
    <li><code>CMBlockBufferReplaceDataBytes</code> to write the H.264 in AVCC format to the memory block</li>
    <li><code>CMSampleBufferCreate</code> to create a sample buffer with the memory block and a format descriptor containing the H.264 "extradata"</li>
    </ol>
  </blockquote>
  
  <p>Everything works as expected, the only problem with this approach is that I'm periodically calling the above APIs and what I would really like is instead to be able to reuse the resources allocated - in particular <code>CMSampleBufferRef</code> and <code>CMBlockBufferRef</code>. <strong>Basically, I would like to have a pool of <code>CMSampleBuffer</code>'s and be able to update its memory content and format descriptor as I'm receiving new H.264 data from the remote server</strong>.</p>
  
  <p>I know that exists <code>AVAssetWriterInputPixelBufferAdaptor</code>that gives access to a <code>CVPixelBufferPool</code> but, I can't use it in my case because as far as I know, to properly instantiate a pixel buffer adaptor, at minimum I need to be able to pass the video frame dimensions which I would' know until I  parse the stream. Further, I don't know how to write the H.264 "extradata" with a <code>CVPixelBuffer</code>. So, I'm thinking that I need to stick with <code>CMSampleBuffer</code>. Unfortunately, it seems that CoreMedia APIs don't offer the possibility to update the memory block nor the format descriptor of a sample buffer once created (as far as I can tell, I only have access to immutable references of those objects). Thus, the best I can do so far is to reuse the memory block <code>CMBlockBufferRef</code> but I'm still recreating the sample buffer. My code is below. Hopefully someone here will have some ideas on how to implement a pool of <code>CMSampleBuffer</code>'s or perhaps a more efficient way to write H.264 AVCC stream to MP4?</p>
  
  <pre><code>- (CMSampleBufferRef)sampleBufferWithData:(NSData*)data formatDescriptor:(CMFormatDescriptionRef)formatDescription
  {
      OSStatus result;
  
      CMSampleBufferRef sampleBuffer = NULL;
  
      // _blockBuffer is a CMBlockBufferRef instance variable
      if (!_blockBuffer)
      {
          size_t blockLength = MAX_LENGTH;
          result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
                                                      NULL,
                                                      blockLength,
                                                      kCFAllocatorDefault,
                                                      NULL,
                                                      0,
                                                      blockLength,
                                                      kCMBlockBufferAssureMemoryNowFlag,
                                                      &amp;_blockBuffer);
  
          // check error
      }
  
      result = CMBlockBufferReplaceDataBytes([data bytes], _blockBuffer, 0, [data length]);
  
      // check error
  
      const size_t sampleSizes = [data length];
  
      CMSampleTimingInfo timing = [self sampleTimingInfo];
  
      result = CMSampleBufferCreate(kCFAllocatorDefault,
                                    _blockBuffer,
                                    YES,
                                    NULL,
                                    NULL,
                                    formatDescription,
                                    1,
                                    1,
                                    &amp;timing,
                                    1,
                                    &amp;sampleSizes,
                                    &amp;sampleBuffer);
  
      // check error
  
      return sampleBuffer;
  }
  </code></pre>