Example #1
0
File: vtb.c Project: Ezio-PS/movian
static int
video_vtb_codec_create(media_codec_t *mc, const media_codec_params_t *mcp,
		       media_pipe_t *mp)
{
  OSStatus status;

  if(!video_settings.video_accel)
    return 1;

  switch(mc->codec_id) {
  case AV_CODEC_ID_H264:
    break;
  default:
    return 1;
  }


  if(mcp == NULL || mcp->extradata == NULL || mcp->extradata_size == 0 ||
     ((const uint8_t *)mcp->extradata)[0] != 1)
    return h264_annexb_to_avc(mc, mp, &video_vtb_codec_create);

  CFMutableDictionaryRef config_dict =
    CFDictionaryCreateMutable(kCFAllocatorDefault,
                              2,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);

  CFDictionarySetValue(config_dict,
                       kCVImageBufferChromaLocationBottomFieldKey,
                       kCVImageBufferChromaLocation_Left);

  CFDictionarySetValue(config_dict,
                       kCVImageBufferChromaLocationTopFieldKey,
                       kCVImageBufferChromaLocation_Left);

  // Setup extradata
  CFMutableDictionaryRef extradata_dict =
    CFDictionaryCreateMutable(kCFAllocatorDefault,
                              1,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);


  CFDataRef extradata = CFDataCreate(kCFAllocatorDefault, mcp->extradata,
                                     mcp->extradata_size);
  CFDictionarySetValue(extradata_dict, CFSTR("avcC"), extradata);
  CFRelease(extradata);
  CFDictionarySetValue(config_dict,
                       kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
                       extradata_dict);
  CFRelease(extradata_dict);

#if !TARGET_OS_IPHONE
  // Enable and force HW accelration
  CFDictionarySetValue(config_dict,
                       kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder,
                       kCFBooleanTrue);

  CFDictionarySetValue(config_dict,
                       kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder,
                       kCFBooleanTrue);
#endif

  CMVideoFormatDescriptionRef fmt;

  status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
                                          kCMVideoCodecType_H264,
                                          mcp->width,
                                          mcp->height,
                                          config_dict,
                                          &fmt);
  if(status) {
    TRACE(TRACE_DEBUG, "VTB", "Unable to create description %d", status);
    return 1;
  }


  CFMutableDictionaryRef surface_dict =
    CFDictionaryCreateMutable(kCFAllocatorDefault,
                              2,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);

  CFDictionarySetValue(surface_dict,
#if !TARGET_OS_IPHONE
                       kCVPixelBufferOpenGLCompatibilityKey,
#else
                       kCVPixelBufferOpenGLESCompatibilityKey,
#endif
                       kCFBooleanTrue);

  vtb_decoder_t *vtbd = calloc(1, sizeof(vtb_decoder_t));

  dict_set_int32(surface_dict, kCVPixelBufferWidthKey, mcp->width);
  dict_set_int32(surface_dict, kCVPixelBufferHeightKey, mcp->height);

#if TARGET_OS_IPHONE
    vtbd->vtbd_pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
#else
    vtbd->vtbd_pixel_format = kCVPixelFormatType_420YpCbCr8Planar;
#endif

  dict_set_int32(surface_dict, kCVPixelBufferPixelFormatTypeKey,
                 vtbd->vtbd_pixel_format);

  int linewidth = mcp->width;

  switch(vtbd->vtbd_pixel_format) {
    case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
    case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
      linewidth *= 2;
      break;
  }

  dict_set_int32(surface_dict, kCVPixelBufferBytesPerRowAlignmentKey, linewidth);

  VTDecompressionOutputCallbackRecord cb = {
    .decompressionOutputCallback = picture_out,
    .decompressionOutputRefCon = vtbd
  };

  /* create decompression session */
  status = VTDecompressionSessionCreate(kCFAllocatorDefault,
                                        fmt,
                                        config_dict,
                                        surface_dict,
                                        &cb,
                                        &vtbd->vtbd_session);

  CFRelease(config_dict);
  CFRelease(surface_dict);

  if(status) {
    TRACE(TRACE_DEBUG, "VTB", "Failed to open -- %d", status);
    CFRelease(fmt);
    return 1;

  }
  vtbd->vtbd_fmt = fmt;
  vtbd->vtbd_max_ts   = PTS_UNSET;
  vtbd->vtbd_flush_to = PTS_UNSET;
  vtbd->vtbd_last_pts = PTS_UNSET;

  mc->opaque = vtbd;
  mc->decode = vtb_decode;
  mc->close = vtb_close;
  mc->flush = vtb_flush;

  TRACE(TRACE_DEBUG, "VTB", "Opened decoder");
  return 0;
}
Example #2
0
static int
video_vda_codec_create(media_codec_t *mc, const media_codec_params_t *mcp,
		       media_pipe_t *mp)
{
  OSStatus status = kVDADecoderNoErr;
  CFNumberRef height;
  CFNumberRef width;
  CFNumberRef format;
  CFDataRef avc_data;
  CFMutableDictionaryRef ci;
  CFMutableDictionaryRef ba;
  CFMutableDictionaryRef isp;
  CFNumberRef cv_pix_fmt;
  int zero_copy = 1;

  if(mc->codec_id != AV_CODEC_ID_H264 || !video_settings.vda)
    return 1;

  if(mcp == NULL || mcp->extradata == NULL || mcp->extradata_size == 0 ||
     ((const uint8_t *)mcp->extradata)[0] != 1)
    return h264_annexb_to_avc(mc, mp, &video_vda_codec_create);

  const int pixfmt = zero_copy ?
    kCVPixelFormatType_422YpCbCr8 :
    kCVPixelFormatType_420YpCbCr8Planar;

  const int avc1 = 'avc1';

  ci = CFDictionaryCreateMutable(kCFAllocatorDefault,
				 4,
				 &kCFTypeDictionaryKeyCallBacks,
				 &kCFTypeDictionaryValueCallBacks);

  height   = CFNumberCreate(NULL, kCFNumberSInt32Type, &mcp->height);
  width    = CFNumberCreate(NULL, kCFNumberSInt32Type, &mcp->width);
  format   = CFNumberCreate(NULL, kCFNumberSInt32Type, &avc1);
  avc_data = CFDataCreate(NULL, mcp->extradata, mcp->extradata_size);

  CFDictionarySetValue(ci, kVDADecoderConfiguration_Height, height);
  CFDictionarySetValue(ci, kVDADecoderConfiguration_Width, width);
  CFDictionarySetValue(ci, kVDADecoderConfiguration_SourceFormat, format);
  CFDictionarySetValue(ci, kVDADecoderConfiguration_avcCData, avc_data);

  ba = CFDictionaryCreateMutable(NULL,
				 2,
				 &kCFTypeDictionaryKeyCallBacks,
				 &kCFTypeDictionaryValueCallBacks);
  isp = CFDictionaryCreateMutable(NULL,
				  0,
				  &kCFTypeDictionaryKeyCallBacks,
				  &kCFTypeDictionaryValueCallBacks);
  cv_pix_fmt      = CFNumberCreate(NULL,
				   kCFNumberSInt32Type,
				   &pixfmt);

  CFDictionarySetValue(ba, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
  CFDictionarySetValue(ba, kCVPixelBufferIOSurfacePropertiesKey, isp);
  
  vda_decoder_t *vdad = calloc(1, sizeof(vda_decoder_t));
  vdad->vdad_zero_copy = zero_copy;
  status = VDADecoderCreate(ci, ba, (void *)vda_callback,
			    vdad, &vdad->vdad_decoder);

  CFRelease(height);
  CFRelease(width);
  CFRelease(format);
  CFRelease(avc_data);
  CFRelease(ci);
  CFRelease(isp);
  CFRelease(cv_pix_fmt);
  CFRelease(ba);

  if(kVDADecoderNoErr != status) {
    free(vdad);
    return 1;
  }

  hts_mutex_init(&vdad->vdad_mutex);
  vdad->vdad_max_ts   = PTS_UNSET;
  vdad->vdad_flush_to = PTS_UNSET;
  vdad->vdad_last_pts = PTS_UNSET;
  vdad->vdad_mc = mc;
  mc->opaque = vdad;
  mc->decode = vda_decode;
  mc->close = vda_close;
  mc->flush = vda_flush;

  TRACE(TRACE_DEBUG, "VDA", "Opened decoder");
  return 0;
}