Beispiel #1
0
bool CDVDVideoCodecVDA::GetPicture(DVDVideoPicture* pDvdVideoPicture)
{
  CCocoaAutoPool pool;
  FourCharCode pixel_buffer_format;
  CVPixelBufferRef picture_buffer_ref;

  // clone the video picture buffer settings.
  *pDvdVideoPicture = m_videobuffer;

  // get the top yuv frame, we risk getting the wrong frame if the frame queue
  // depth is less than the number of encoded reference frames. If queue depth
  // is greater than the number of encoded reference frames, then the top frame
  // will never change and we can just grab a ref to the top frame. This way
  // we don't lockout the vdadecoder while doing color format convert.
  pthread_mutex_lock(&m_queue_mutex);
  picture_buffer_ref = m_display_queue->pixel_buffer_ref;
  pixel_buffer_format = m_display_queue->pixel_buffer_format;
  pDvdVideoPicture->dts = m_display_queue->dts;
  pDvdVideoPicture->pts = m_display_queue->pts;
  pthread_mutex_unlock(&m_queue_mutex);

  // lock the CVPixelBuffer down
  CVPixelBufferLockBaseAddress(picture_buffer_ref, 0);
  int row_stride = CVPixelBufferGetBytesPerRowOfPlane(picture_buffer_ref, 0);
  uint8_t *base_ptr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(picture_buffer_ref, 0);
  if (base_ptr)
  {
    if (pixel_buffer_format == kCVPixelFormatType_422YpCbCr8)
      UYVY422_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
    else if (pixel_buffer_format == kCVPixelFormatType_32BGRA)
      BGRA_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
  }
  // unlock the CVPixelBuffer
  CVPixelBufferUnlockBaseAddress(picture_buffer_ref, 0);

  // now we can pop the top frame.
  DisplayQueuePop();

  //CLog::Log(LOGNOTICE, "%s - VDADecoderDecode dts(%f), pts(%f)", __FUNCTION__,
  //  pDvdVideoPicture->dts, pDvdVideoPicture->pts);

  return VC_PICTURE | VC_BUFFER;
}
Beispiel #2
0
bool CDVDVideoCodecVDA::GetPicture(DVDVideoPicture* pDvdVideoPicture)
{
  // get the top yuv frame, we risk getting the wrong frame if the frame queue
  // depth is less than the number of encoded reference frames. If queue depth
  // is greater than the number of encoded reference frames, then the top frame
  // will never change and we can just grab a ref to the top frame.
  if (m_use_cvBufferRef)
  {
    pthread_mutex_lock(&m_queue_mutex);
    pDvdVideoPicture->dts             = m_display_queue->dts;
    pDvdVideoPicture->pts             = m_display_queue->pts;
    pDvdVideoPicture->cvBufferRef     = m_display_queue->pixel_buffer_ref;
    m_display_queue->pixel_buffer_ref = NULL;
    pthread_mutex_unlock(&m_queue_mutex);

    pDvdVideoPicture->format          = RENDER_FMT_CVBREF;
    pDvdVideoPicture->iFlags          = DVP_FLAG_ALLOCATED;
    pDvdVideoPicture->color_range     = 0;
    pDvdVideoPicture->color_matrix    = 4;
    pDvdVideoPicture->iWidth          = CVPixelBufferGetWidth(pDvdVideoPicture->cvBufferRef);
    pDvdVideoPicture->iHeight         = CVPixelBufferGetHeight(pDvdVideoPicture->cvBufferRef);
    pDvdVideoPicture->iDisplayWidth   = pDvdVideoPicture->iWidth;
    pDvdVideoPicture->iDisplayHeight  = pDvdVideoPicture->iHeight;
  }
  else
  {
    FourCharCode pixel_buffer_format;
    CVPixelBufferRef picture_buffer_ref;

    // clone the video picture buffer settings.
    *pDvdVideoPicture = m_videobuffer;

    // get the top yuv frame, we risk getting the wrong frame if the frame queue
    // depth is less than the number of encoded reference frames. If queue depth
    // is greater than the number of encoded reference frames, then the top frame
    // will never change and we can just grab a ref to the top frame. This way
    // we don't lockout the vdadecoder while doing color format convert.
    pthread_mutex_lock(&m_queue_mutex);
    picture_buffer_ref = m_display_queue->pixel_buffer_ref;
    pixel_buffer_format = m_display_queue->pixel_buffer_format;
    pDvdVideoPicture->dts = m_display_queue->dts;
    pDvdVideoPicture->pts = m_display_queue->pts;
    pthread_mutex_unlock(&m_queue_mutex);

    // lock the CVPixelBuffer down
    CVPixelBufferLockBaseAddress(picture_buffer_ref, 0);
    int row_stride = CVPixelBufferGetBytesPerRowOfPlane(picture_buffer_ref, 0);
    uint8_t *base_ptr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(picture_buffer_ref, 0);
    if (base_ptr)
    {
      if (pixel_buffer_format == kCVPixelFormatType_422YpCbCr8)
        UYVY422_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
      else if (pixel_buffer_format == kCVPixelFormatType_32BGRA)
        BGRA_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
    }
    // unlock the CVPixelBuffer
    CVPixelBufferUnlockBaseAddress(picture_buffer_ref, 0);
  }

  // now we can pop the top frame.
  DisplayQueuePop();
  //CLog::Log(LOGNOTICE, "%s - VDADecoderDecode dts(%f), pts(%f)", __FUNCTION__,
  //  pDvdVideoPicture->dts, pDvdVideoPicture->pts);

  return true;
}