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); }
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; }
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; }