Beispiel #1
0
static void
vdpau_codec_reinit(media_codec_t *mc)
{
  vdpau_codec_t *vc = mc->opaque;
  vdpau_dev_t *vd = vc->vc_vd;
  vdpau_video_surface_t *vvs;
  VdpStatus r;

  r = vd->vdp_decoder_create(vd->vd_dev, vc->vc_profile, 
			     vc->vc_width, vc->vc_height,
			     vc->vc_refframes, &vc->vc_decoder);

  if(r != VDP_STATUS_OK) {
    TRACE(TRACE_INFO, "VDPAU", "Unable to reinit decoder: %s",
	  vdpau_errstr(vd, r));
    return;
  }

  TAILQ_FOREACH(vvs, &vc->vc_vvs_free, vvs_link)
    vd->vdp_video_surface_create(vd->vd_dev, VDP_CHROMA_TYPE_420,
				 vc->vc_width, vc->vc_height,
				 &vvs->vvs_surface);
  
  TAILQ_FOREACH(vvs, &vc->vc_vvs_alloc, vvs_link)
    vd->vdp_video_surface_create(vd->vd_dev, VDP_CHROMA_TYPE_420,
				 vc->vc_width, vc->vc_height,
				 &vvs->vvs_surface);
  
}
Beispiel #2
0
int
vdpau_codec_create(media_codec_t *mc, enum CodecID id,
		   AVCodecContext *ctx, media_codec_params_t *mcp,
		   media_pipe_t *mp)
{
  VdpDecoderProfile profile;
  vdpau_dev_t *vd = mp->mp_vdpau_dev;
  VdpStatus r;
  int refframes;

  if(vd == NULL)
    return 1;

  if(mcp->width == 0 || mcp->height == 0)
    return 1;

  switch(id) {

  case CODEC_ID_MPEG1VIDEO:
    profile = VDP_DECODER_PROFILE_MPEG1; 
    mc->codec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
    refframes = 2;
    break;

  case CODEC_ID_MPEG2VIDEO:
    profile = VDP_DECODER_PROFILE_MPEG2_MAIN; 
    mc->codec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
    refframes = 2;
    break;

  case CODEC_ID_H264:
    profile = VDP_DECODER_PROFILE_H264_HIGH; 
    mc->codec = avcodec_find_decoder_by_name("h264_vdpau");
    refframes = 16;
    break;
#if 0 // Seems broken
  case CODEC_ID_VC1:
    profile = VDP_DECODER_PROFILE_VC1_ADVANCED; 
    mc->codec = avcodec_find_decoder_by_name("vc1_vdpau");
    refframes = 16;
    break;

  case CODEC_ID_WMV3:
    profile = VDP_DECODER_PROFILE_VC1_MAIN;
    mc->codec = avcodec_find_decoder_by_name("wmv3_vdpau");
    refframes = 16;
    break;
#endif
  default:
    return 1;
  }

  if(mc->codec == NULL)
    return -1;

  vdpau_codec_t *vc = calloc(1, sizeof(vdpau_codec_t));
  TAILQ_INIT(&vc->vc_vvs_alloc);
  TAILQ_INIT(&vc->vc_vvs_free);
  vc->vc_vd = vd;
  vc->vc_width = mcp->width;
  vc->vc_height = mcp->height;
  vc->vc_profile = profile;
  vc->vc_refframes = refframes;

  r = vd->vdp_decoder_create(vd->vd_dev, vc->vc_profile, 
			     vc->vc_width, vc->vc_height,
			     vc->vc_refframes, &vc->vc_decoder);

  if(r != VDP_STATUS_OK) {
    TRACE(TRACE_INFO, "VDPAU", "Unable to create decoder: %s",
	  vdpau_errstr(vd, r));
    vc_destroy(vc);
    return -1;
  }

  
  r = vdpau_create_buffers(vc, vc->vc_width, vc->vc_height,
			   vc->vc_refframes + 5);

  if(r != VDP_STATUS_OK) {
    TRACE(TRACE_INFO, "VDPAU", "Unable to allocate decoding buffers");
    vc_destroy(vc);
    return -1;
  }

  TRACE(TRACE_DEBUG, "VDPAU", "Decoder initialized");
	  
  mc->codec_ctx = ctx ?: avcodec_alloc_context();
  mc->codec_ctx->codec_id   = mc->codec->id;
  mc->codec_ctx->codec_type = mc->codec->type;

  if(avcodec_open(mc->codec_ctx, mc->codec) < 0) {
    if(ctx == NULL)
      free(mc->codec_ctx);
    mc->codec = NULL;
    vc_destroy(vc);
    return -1;
  }

  mc->codec_ctx->get_buffer      = vdpau_get_buffer;
  mc->codec_ctx->release_buffer  = vdpau_release_buffer;
  mc->codec_ctx->draw_horiz_band = vdpau_draw_horiz_band;
  mc->codec_ctx->get_format      = vdpau_get_pixfmt;

  mc->codec_ctx->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;

  mc->codec_ctx->opaque = mc;
  mc->opaque = vc;
  mc->decode = vdpau_decode;
  mc->close  = vdpau_codec_close;
  mc->reinit = vdpau_codec_reinit;
  return 0;
}
Beispiel #3
0
static int
vdpau_codec_create(media_codec_t *mc, const media_codec_params_t *mcp,
		   media_pipe_t *mp)
{
  VdpDecoderProfile profile;
  vdpau_dev_t *vd = mp->mp_vdpau_dev;
  VdpStatus r;
  int refframes;
  AVCodec *codec;

  if(vd == NULL)
    return 1;

  if(mcp == NULL || mcp->width == 0 || mcp->height == 0)
    return 1;

  switch(mc->codec_id) {

  case CODEC_ID_MPEG1VIDEO:
    profile = VDP_DECODER_PROFILE_MPEG1; 
    codec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
    refframes = 2;
    break;

  case CODEC_ID_MPEG2VIDEO:
    profile = VDP_DECODER_PROFILE_MPEG2_MAIN; 
    codec = avcodec_find_decoder_by_name("mpegvideo_vdpau");
    refframes = 2;
    break;

  case CODEC_ID_H264:
    profile = VDP_DECODER_PROFILE_H264_HIGH; 
    codec = avcodec_find_decoder_by_name("h264_vdpau");
    refframes = 16;
    break;
#if 0 // Seems broken
  case CODEC_ID_VC1:
    profile = VDP_DECODER_PROFILE_VC1_ADVANCED; 
    mc->codec = avcodec_find_decoder_by_name("vc1_vdpau");
    refframes = 16;
    break;

  case CODEC_ID_WMV3:
    profile = VDP_DECODER_PROFILE_VC1_MAIN;
    mc->codec = avcodec_find_decoder_by_name("wmv3_vdpau");
    refframes = 16;
    break;
#endif
  default:
    return 1;
  }

  if(codec == NULL)
    return -1;

  vdpau_codec_t *vc = calloc(1, sizeof(vdpau_codec_t));
  TAILQ_INIT(&vc->vc_vvs_alloc);
  TAILQ_INIT(&vc->vc_vvs_free);
  vc->vc_vd = vd;
  vc->vc_width = mcp->width;

  if(mcp->height == 1088)
    vc->vc_height = 1080;
  else
    vc->vc_height = mcp->height;

  vc->vc_profile = profile;
  vc->vc_refframes = refframes;

  r = vd->vdp_decoder_create(vd->vd_dev, vc->vc_profile, 
			     vc->vc_width, vc->vc_height,
			     vc->vc_refframes, &vc->vc_decoder);

  if(r != VDP_STATUS_OK) {
    TRACE(TRACE_INFO, "VDPAU", "Unable to create decoder: %s",
	  vdpau_errstr(vd, r));
    vc_destroy(vc);
    return -1;
  }

  
  r = vdpau_create_buffers(vc, vc->vc_width, vc->vc_height,
			   vc->vc_refframes + 5);

  if(r != VDP_STATUS_OK) {
    TRACE(TRACE_INFO, "VDPAU", "Unable to allocate decoding buffers");
    vc_destroy(vc);
    return -1;
  }

  TRACE(TRACE_DEBUG, "VDPAU", "Decoder initialized");
	  
  mc->ctx = avcodec_alloc_context3(codec);

  if(mcp->extradata != NULL) {
    mc->ctx->extradata = calloc(1, mcp->extradata_size +
				FF_INPUT_BUFFER_PADDING_SIZE);
    memcpy(mc->ctx->extradata, mcp->extradata, mcp->extradata_size);
    mc->ctx->extradata_size = mcp->extradata_size;
  }

  if(avcodec_open2(mc->ctx, codec, NULL) < 0) {
    free(mc->ctx);
    vc_destroy(vc);
    return -1;
  }

  mc->ctx->get_buffer      = vdpau_get_buffer;
  mc->ctx->release_buffer  = vdpau_release_buffer;
  mc->ctx->draw_horiz_band = vdpau_draw_horiz_band;
  mc->ctx->get_format      = vdpau_get_pixfmt;

  mc->ctx->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;

  mc->ctx->opaque = mc;
  mc->opaque = vc;
  mc->decode = vdpau_decode;
  mc->flush  = video_flush_avctx;
  mc->close  = vdpau_codec_close;
  mc->reinit = vdpau_codec_reinit;
  return 0;
}