title: CMBlockBufferGetDataPointer datapointer is empty
body: <p>I am trying to send a H264 elementary stream to a server via TCP. The video is coming from the camera then straight to the device's encoder.  The Media server is unable to playback the video it received from the iOS app. I saved the stream buffer to a file an open it in an H264 analyser and I think it is missing some video data(non-IDR perhaps). Some of my code was taken from another post here in Stackoverflow(Outputcallback) while the encoding part from another source file online. I was checking for the CMBlockBufferGetDataPointer if it has some value but it is always empty. I am not sure if that is the reason why the stream is not playing on the other end. I hope you could tell me what is missing and what I could fix.</p>
  
  <pre><code>static void OutputCallback(void *outputCallbackRefCon,
                                     void *sourceFrameRefCon,
                                     OSStatus status,
                                     VTEncodeInfoFlags infoFlags,
                                     CMSampleBufferRef sampleBuffer) {
  // Check if there were any errors encoding
  if (status != noErr) {
      NSLog(@"Error encoding video, err=%lld", (int64_t)status);
      return;
  }
  
  // In this example we will use a NSMutableData object to store the
  // elementary stream.
  NSMutableData *elementaryStream = [NSMutableData data];
  
  
  // Find out if the sample buffer contains an I-Frame.
  // If so we will write the SPS and PPS NAL units to the elementary stream.
  BOOL isIFrame = NO;
  CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, 0);
  if (CFArrayGetCount(attachmentsArray)) {
      CFBooleanRef notSync;
      CFDictionaryRef dict = CFArrayGetValueAtIndex(attachmentsArray, 0);
      BOOL keyExists = CFDictionaryGetValueIfPresent(dict,
                                                     kCMSampleAttachmentKey_NotSync,
                                                     (const void **)&amp;notSync);
      // An I-Frame is a sync frame
      isIFrame = !keyExists || !CFBooleanGetValue(notSync);
  }
  
  // This is the start code that we will write to
  // the elementary stream before every NAL unit
  static const size_t startCodeLength = 4;
  static const uint8_t startCode[] = {0x00, 0x00, 0x00, 0x01};
  
  // Write the SPS and PPS NAL units to the elementary stream before every I-Frame
  if (isIFrame) {
      CMFormatDescriptionRef description = CMSampleBufferGetFormatDescription(sampleBuffer);
  
      // Find out how many parameter sets there are
      size_t numberOfParameterSets;
      CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description,
                                                         0, NULL, NULL,
                                                         &amp;numberOfParameterSets,
                                                         NULL);
  
      // Write each parameter set to the elementary stream
      for (int i = 0; i &lt; numberOfParameterSets; i++) {
          const uint8_t *parameterSetPointer;
          size_t parameterSetLength;
          CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description,
                                                             i,
                                                             &amp;parameterSetPointer,
                                                             &amp;parameterSetLength,
                                                             NULL, NULL);
  
          // Write the parameter set to the elementary stream
          [elementaryStream appendBytes:startCode length:startCodeLength];
          [elementaryStream appendBytes:parameterSetPointer length:parameterSetLength];
      }
  }
  
  // Get a pointer to the raw AVCC NAL unit data in the sample buffer
  size_t blockBufferLength;
  uint8_t *bufferDataPointer = NULL;
  CMBlockBufferGetDataPointer(CMSampleBufferGetDataBuffer(sampleBuffer),
                              0,
                              NULL,
                              &amp;blockBufferLength,
                              (char **)&amp;bufferDataPointer);
  
  // Loop through all the NAL units in the block buffer
  // and write them to the elementary stream with
  // start codes instead of AVCC length headers
  size_t bufferOffset = 0;
  static const int AVCCHeaderLength = 4;
  while (bufferOffset &lt; blockBufferLength - AVCCHeaderLength) {
      // Read the NAL unit length
      uint32_t NALUnitLength = 0;
      memcpy(&amp;NALUnitLength, bufferDataPointer + bufferOffset, AVCCHeaderLength);
      // Convert the length value from Big-endian to Little-endian
      NALUnitLength = CFSwapInt32BigToHost(NALUnitLength);
      // Write start code to the elementary stream
      [elementaryStream appendBytes:startCode length:startCodeLength];
      // Write the NAL unit without the AVCC length header to the elementary stream
      [elementaryStream appendBytes:bufferDataPointer + bufferOffset + AVCCHeaderLength
                             length:NALUnitLength];
      // Move to the next NAL unit in the block buffer
      bufferOffset += AVCCHeaderLength + NALUnitLength;
  }
  }   
  
   -(void)compressSample:(CMSampleBufferRef)sampleBuffer {
  CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
  
  size_t width = CVPixelBufferGetWidth(imageBuffer);
  size_t height = CVPixelBufferGetHeight(imageBuffer);
  
  VTCompressionSessionRef session;
  OSStatus ret = VTCompressionSessionCreate(NULL, (int)width, (int)height, kCMVideoCodecType_H264, NULL, NULL, NULL, OutputCallback, (__bridge void * _Nullable)(self), &amp;session);
  if (ret == noErr) {
  
      VTSessionSetProperty(session, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
  
  
      CMTime xpts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
      //kCMTimeInvalid
      VTCompressionSessionEncodeFrame(session, imageBuffer, xpts, kCMTimeInvalid, NULL, NULL, NULL);
      VTCompressionSessionEndPass(session, false, NULL);
  }else{
      NSLog(@"Error encoding");
  }
  
  if (session) {
      VTCompressionSessionInvalidate(session);
      CFRelease(session);
  }
  }
  </code></pre>