コード例 #1
0
ファイル: hwacc_vaapi.cpp プロジェクト: akhilo/cmplayer
void HwAccVaApi::freeContext() {
	if (d->context.display) {
		if (d->context.context_id != VA_INVALID_ID)
			vaDestroyContext(d->context.display, d->context.context_id);
	}
	d->context.context_id = VA_INVALID_ID;
}
コード例 #2
0
Decode_Status VaapiDecoderBase::terminateVA(void)
{
    INFO("base: terminate VA");
    if (m_bufPool) {
        delete m_bufPool;
        m_bufPool = NULL;
    }

    if (m_VAContext != VA_INVALID_ID) {
        vaDestroyContext(m_VADisplay, m_VAContext);
        m_VAContext = VA_INVALID_ID;
    }

    if (m_VAConfig != VA_INVALID_ID) {
        vaDestroyConfig(m_VADisplay, m_VAConfig);
        m_VAConfig = VA_INVALID_ID;
    }

    if (m_VADisplay) {
        vaTerminate(m_VADisplay);
        m_VADisplay = NULL;
    }
#ifdef ANDROID
    delete m_display;
#else
    if (m_display && m_ownNativeDisplay) {
        XCloseDisplay(m_display);
    }
#endif
    m_display = NULL;

    m_VAStarted = false;
    return DECODE_SUCCESS;
}
コード例 #3
0
ファイル: vaapi.c プロジェクト: repstd/modified_vlc
static void DestroySurfaces( vlc_va_vaapi_t *p_va )
{
    if( p_va->image.image_id != VA_INVALID_ID )
    {
        CopyCleanCache( &p_va->image_cache );
        vaDestroyImage( p_va->p_display, p_va->image.image_id );
    }
    else if(p_va->b_supports_derive)
    {
        CopyCleanCache( &p_va->image_cache );
    }

    if( p_va->i_context_id != VA_INVALID_ID )
        vaDestroyContext( p_va->p_display, p_va->i_context_id );

    for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ )
    {
        vlc_va_surface_t *p_surface = &p_va->p_surface[i];

        if( p_surface->i_id != VA_INVALID_SURFACE )
            vaDestroySurfaces( p_va->p_display, &p_surface->i_id, 1 );
    }
    free( p_va->p_surface );

    /* */
    p_va->image.image_id = VA_INVALID_ID;
    p_va->i_context_id = VA_INVALID_ID;
    p_va->p_surface = NULL;
    p_va->i_surface_width = 0;
    p_va->i_surface_height = 0;
}
コード例 #4
0
ファイル: vaapi_encode.c プロジェクト: 0xheart0/FFmpeg
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
{
    VAAPIEncodeContext *ctx = avctx->priv_data;
    VAAPIEncodePicture *pic, *next;

    for (pic = ctx->pic_start; pic; pic = next) {
        next = pic->next;
        vaapi_encode_free(avctx, pic);
    }

    if (ctx->va_context != VA_INVALID_ID)
        vaDestroyContext(ctx->hwctx->display, ctx->va_context);

    if (ctx->va_config != VA_INVALID_ID)
        vaDestroyConfig(ctx->hwctx->display, ctx->va_config);

    if (ctx->codec->close)
        ctx->codec->close(avctx);

    av_freep(&ctx->codec_sequence_params);
    av_freep(&ctx->codec_picture_params);

    av_buffer_unref(&ctx->recon_frames_ref);
    av_buffer_unref(&ctx->input_frames_ref);
    av_buffer_unref(&ctx->device_ref);

    av_freep(&ctx->priv_data);

    return 0;
}
コード例 #5
0
ファイル: vaapi_decode.c プロジェクト: Emerica/FFmpeg
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
{
    VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
    VAStatus vas;

#if FF_API_STRUCT_VAAPI_CONTEXT
    if (ctx->have_old_context) {
        av_buffer_unref(&ctx->device_ref);
    } else {
#endif

    if (ctx->va_context != VA_INVALID_ID) {
        vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
        if (vas != VA_STATUS_SUCCESS) {
            av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
                   "context %#x: %d (%s).\n",
                   ctx->va_context, vas, vaErrorStr(vas));
        }
    }
    if (ctx->va_config != VA_INVALID_ID) {
        vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
        if (vas != VA_STATUS_SUCCESS) {
            av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
                   "configuration %#x: %d (%s).\n",
                   ctx->va_config, vas, vaErrorStr(vas));
        }
    }

#if FF_API_STRUCT_VAAPI_CONTEXT
    }
#endif

    return 0;
}
コード例 #6
0
ファイル: vf_deinterlace_vaapi.c プロジェクト: bavison/FFmpeg
static int deint_vaapi_pipeline_uninit(AVFilterContext *avctx)
{
    DeintVAAPIContext *ctx = avctx->priv;
    int i;

    for (i = 0; i < ctx->queue_count; i++)
        av_frame_free(&ctx->frame_queue[i]);
    ctx->queue_count = 0;

    if (ctx->filter_buffer != VA_INVALID_ID) {
        vaDestroyBuffer(ctx->hwctx->display, ctx->filter_buffer);
        ctx->filter_buffer = VA_INVALID_ID;
    }

    if (ctx->va_context != VA_INVALID_ID) {
        vaDestroyContext(ctx->hwctx->display, ctx->va_context);
        ctx->va_context = VA_INVALID_ID;
    }

    if (ctx->va_config != VA_INVALID_ID) {
        vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
        ctx->va_config = VA_INVALID_ID;
    }

    av_buffer_unref(&ctx->device_ref);
    ctx->hwctx = NULL;

    return 0;
}
コード例 #7
0
ファイル: VideoDecoderVAAPI.cpp プロジェクト: deaware/QtAV
void VideoDecoderVAAPIPrivate::destroySurfaces()
{
    if (image.image_id != VA_INVALID_ID) {
        //CopyCleanCache(&sys->image_cache);
        vaDestroyImage(display, image.image_id);
    } else if (supports_derive) {
        //CopyCleanCache(&sys->image_cache);
    }

    if (context_id != VA_INVALID_ID)
        vaDestroyContext(display, context_id);

    for (int i = 0; i < nb_surfaces && surfaces; i++) {
        va_surface_t *surface = &surfaces[i];
        if (surface->i_id != VA_INVALID_SURFACE)
            vaDestroySurfaces(display, &surface->i_id, 1);
    }
    //qDeleteAll(surfaces);
    //surfaces.clear();
    free(surfaces);
    surfaces = 0;
    /* */
    image.image_id = VA_INVALID_ID;
    context_id = VA_INVALID_ID;
    surface_width = 0;
    surface_height = 0;
    //vlc_mutex_destroy(&sys->lock);
}
コード例 #8
0
ファイル: hwacc_vaapi.cpp プロジェクト: akhilo/cmplayer
void VaApi::initFilters() {
	if (!hasEntryPoint(VAEntrypointVideoProc, VAProfileNone))
		return;
	auto display = VaApi::glx();
	VAConfigID config = VA_INVALID_ID;
	VAContextID context = VA_INVALID_ID;
	do {
		if (!isSuccess(vaCreateConfig(display, VAProfileNone, VAEntrypointVideoProc, nullptr, 0, &config)))
			break;
		if (!isSuccess(vaCreateContext(display, config, 0, 0, 0, nullptr, 0, &context)))
			break;
		QVector<VAProcFilterType> types(VAProcFilterCount);
		uint size = VAProcFilterCount;
		if (!isSuccess(vaQueryVideoProcFilters(display, context, types.data(), &size)))
			break;
		types.resize(size);
		for (const auto &type : types) {
			VaApiFilterInfo info(context, type);
			if (info.isSuccess() && !info.algorithms().isEmpty())
				m_filters.insert(type, info);
		}
	} while (false);
	if (context != VA_INVALID_ID)
		vaDestroyContext(display, context);
	if (config != VA_INVALID_ID)
		vaDestroyConfig(display, config);
}
コード例 #9
0
VaApiPostProcessor::~VaApiPostProcessor() {
	delete d->deinterlacer;
	if (d->context != VA_INVALID_ID)
		vaDestroyContext(d->dpy, d->context);
	if (d->context != VA_INVALID_ID)
		vaDestroyConfig(d->dpy, d->config);
	delete d;
}
コード例 #10
0
static
void
ppb_video_decoder_destroy_priv(void *p)
{
    struct pp_video_decoder_s *vd = p;

    if (vd->orig_graphics3d) {
        pp_resource_unref(vd->orig_graphics3d);
        vd->orig_graphics3d = 0;
    }

    if (vd->graphics3d) {
        pp_resource_unref(vd->graphics3d);
        vd->graphics3d = 0;
    }

    if (vd->avparser) {
        av_parser_close(vd->avparser);
        vd->avparser = NULL;
    }

    if (vd->avctx)
        avcodec_free_context(&vd->avctx);

    if (vd->avframe)
        av_frame_free(&vd->avframe);

    if (vd->va_context.context_id) {
        vaDestroyContext(display.va, vd->va_context.context_id);
        vd->va_context.context_id = 0;
    }

    if (vd->va_context.config_id) {
        vaDestroyConfig(display.va, vd->va_context.config_id);
        vd->va_context.config_id = 0;
    }

    vaDestroySurfaces(display.va, vd->surfaces, MAX_VIDEO_SURFACES);
    for (uintptr_t k = 0; k < MAX_VIDEO_SURFACES; k ++) {
        vd->surfaces[k] = VA_INVALID_SURFACE;
        vd->surface_used[k] = 0;

    }

    for (uintptr_t k = 0; k < vd->buffer_count; k ++) {
        vd->ppp_video_decoder_dev->DismissPictureBuffer(vd->instance->id, vd->self_id,
                                                        vd->buffers[k].id);
        pthread_mutex_lock(&display.lock);
        glXDestroyPixmap(display.x, vd->buffers[k].glx_pixmap);
        XFreePixmap(display.x, vd->buffers[k].pixmap);
        pthread_mutex_unlock(&display.lock);
    }

    vd->buffer_count = 0;
    vd->buffers_were_requested = 0;
    free_and_nullify(vd->buffers);
}
コード例 #11
0
ファイル: vaapicontext.cpp プロジェクト: mojie126/mythtv
VAAPIContext::~VAAPIContext()
{
    delete [] m_pictureAttributes;

    ClearGLXSurfaces();

    if (m_display)
    {
        m_display->m_x_disp->Lock();

        INIT_ST;

        if (m_image.image_id != VA_INVALID_ID)
        {
            va_status = vaDestroyImage(m_ctx.display, m_image.image_id);
            CHECK_ST;
        }
        if (m_ctx.context_id)
        {
            va_status = vaDestroyContext(m_ctx.display, m_ctx.context_id);
            CHECK_ST;
        }
        if (m_ctx.config_id)
        {
            va_status = vaDestroyConfig(m_ctx.display, m_ctx.config_id);
            CHECK_ST;
        }
        if (m_surfaces)
        {
            va_status = vaDestroySurfaces(m_ctx.display, m_surfaces, m_numSurfaces);
            CHECK_ST;
        }
    }

    if (m_surfaces)
        delete [] m_surfaces;
    if (m_surfaceData)
        delete [] m_surfaceData;

    if (m_display)
    {
        m_display->m_x_disp->Unlock();
        m_display->DecrRef();
    }

    delete m_copy;

    LOG(VB_PLAYBACK, LOG_INFO, LOC + "Deleted context");
}
コード例 #12
0
static int scale_vaapi_pipeline_uninit(ScaleVAAPIContext *ctx)
{
    if (ctx->va_context != VA_INVALID_ID) {
        vaDestroyContext(ctx->hwctx->display, ctx->va_context);
        ctx->va_context = VA_INVALID_ID;
    }

    if (ctx->va_config != VA_INVALID_ID) {
        vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
        ctx->va_config = VA_INVALID_ID;
    }

    av_buffer_unref(&ctx->output_frames_ref);
    av_buffer_unref(&ctx->device_ref);
    ctx->hwctx = 0;

    return 0;
}
コード例 #13
0
VdpStatus
softVdpDecoderDestroy(VdpDecoder decoder)
{
    VdpDecoderData *decoderData = handle_acquire(decoder, HANDLETYPE_DECODER);
    if (NULL == decoderData)
        return VDP_STATUS_INVALID_HANDLE;
    VdpDeviceData *deviceData = decoderData->device;

    if (deviceData->va_available) {
        VADisplay va_dpy = deviceData->va_dpy;
        vaDestroySurfaces(va_dpy, decoderData->render_targets, decoderData->num_render_targets);
        vaDestroyContext(va_dpy, decoderData->context_id);
        vaDestroyConfig(va_dpy, decoderData->config_id);
    }

    handle_expunge(decoder);
    deviceData->refcount --;
    free(decoderData);
    return VDP_STATUS_OK;
}
コード例 #14
0
void VaapiEncoderBase::cleanupVA()
{
    if (m_display && m_context) {
        vaDestroyContext(m_display, m_context);
        m_context = VA_INVALID_ID;
    }
    if (m_display && m_config) {
        vaDestroyConfig(m_display, m_config);
        m_config = VA_INVALID_ID;
    }
    if (m_display) {
        vaTerminate(m_display);
        m_display = NULL;
    }
    if (m_xDisplay) {
        if (!m_externalDisplay)
            XCloseDisplay(m_xDisplay);
        m_xDisplay = NULL;
    }
}
コード例 #15
0
ファイル: vaapi.c プロジェクト: 42TheAnswerToLife/vlc
static void Delete( vlc_va_t *va, AVCodecContext *avctx )
{
    vlc_va_sys_t *sys = va->sys;

    (void) avctx;

    vlc_mutex_destroy(&sys->lock);
    CopyCleanCache(&sys->image_cache);

    vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
    vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
    vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id);
    vaTerminate(sys->hw_ctx.display);
#ifdef VLC_VA_BACKEND_XLIB
    XCloseDisplay( sys->p_display_x11 );
#endif
#ifdef VLC_VA_BACKEND_DRM
    close( sys->drm_fd );
#endif
    free( sys );
}
コード例 #16
0
ファイル: h264.c プロジェクト: beijingkaka/shellspace
static void h264_cleanup_decoder()
{
    VAStatus va_status;

    rfbClientLog("%s()\n", __FUNCTION__);

    if (va_surface_id[0] != VA_INVALID_ID) {
        va_status = vaDestroySurfaces(va_dpy, &va_surface_id[0], SURFACE_NUM);
        CHECK_VASTATUS(va_status, "vaDestroySurfaces");
    }

    if (va_context_id) {
        va_status = vaDestroyContext(va_dpy, va_context_id);
        CHECK_VASTATUS(va_status, "vaDestroyContext");
        va_context_id = 0;
    }

    num_frames = 0;
    sid = 0;
    frame_id = 0;
    field_order_count = 0;
}
コード例 #17
0
ファイル: vaapi.c プロジェクト: coog009/myproject
int vaapi_exit(void)
{
    VAAPIContext * const vaapi = vaapi_get_context();
    unsigned int i;

    if (!vaapi)
        return 0;

#if USE_GLX
    if (display_type() == DISPLAY_GLX)
        vaapi_glx_destroy_surface();
#endif

    destroy_buffers(vaapi->display, &vaapi->pic_param_buf_id, 1);
    destroy_buffers(vaapi->display, &vaapi->iq_matrix_buf_id, 1);
    destroy_buffers(vaapi->display, &vaapi->bitplane_buf_id, 1);
    destroy_buffers(vaapi->display, vaapi->slice_buf_ids, vaapi->n_slice_buf_ids);

    if (vaapi->subpic_flags) {
        free(vaapi->subpic_flags);
        vaapi->subpic_flags = NULL;
    }

    if (vaapi->subpic_formats) {
        free(vaapi->subpic_formats);
        vaapi->subpic_formats = NULL;
        vaapi->n_subpic_formats = 0;
    }

    if (vaapi->image_formats) {
        free(vaapi->image_formats);
        vaapi->image_formats = NULL;
        vaapi->n_image_formats = 0;
    }

    if (vaapi->entrypoints) {
        free(vaapi->entrypoints);
        vaapi->entrypoints = NULL;
        vaapi->n_entrypoints = 0;
    }

    if (vaapi->profiles) {
        free(vaapi->profiles);
        vaapi->profiles = NULL;
        vaapi->n_profiles = 0;
    }

    if (vaapi->slice_params) {
        free(vaapi->slice_params);
        vaapi->slice_params = NULL;
        vaapi->slice_params_alloc = 0;
        vaapi->n_slice_params = 0;
    }

    if (vaapi->slice_buf_ids) {
        free(vaapi->slice_buf_ids);
        vaapi->slice_buf_ids = NULL;
        vaapi->n_slice_buf_ids = 0;
    }

    if (vaapi->subpic_image.image_id != VA_INVALID_ID) {
        vaDestroyImage(vaapi->display, vaapi->subpic_image.image_id);
        vaapi->subpic_image.image_id = VA_INVALID_ID;
    }

    for (i = 0; i < ARRAY_ELEMS(vaapi->subpic_ids); i++) {
        if (vaapi->subpic_ids[i] != VA_INVALID_ID) {
            vaDestroySubpicture(vaapi->display, vaapi->subpic_ids[i]);
            vaapi->subpic_ids[i] = VA_INVALID_ID;
        }
    }

    if (vaapi->surface_id) {
        vaDestroySurfaces(vaapi->display, &vaapi->surface_id, 1);
        vaapi->surface_id = 0;
    }

    if (vaapi->context_id) {
        vaDestroyContext(vaapi->display, vaapi->context_id);
        vaapi->context_id = 0;
    }

    if (vaapi->config_id) {
        vaDestroyConfig(vaapi->display, vaapi->config_id);
        vaapi->config_id = 0;
    }

    if (vaapi->display) {
        vaTerminate(vaapi->display);
        vaapi->display = NULL;
    }

    free(vaapi_context);
    return 0;
}
コード例 #18
0
ファイル: vaapi.c プロジェクト: coog009/myproject
int vaapi_init_decoder(VAProfile    profile,
                       VAEntrypoint entrypoint,
                       unsigned int picture_width,
                       unsigned int picture_height)
{
    VAAPIContext * const vaapi = vaapi_get_context();
    VAConfigAttrib attrib;
    VAConfigID config_id = 0;
    VAContextID context_id = 0;
    VASurfaceID surface_id = 0;
    VAStatus status;

    if (!vaapi)
        return -1;
#if 0
    if (common_init_decoder(picture_width, picture_height) < 0)
        return -1;
#endif

    if (!has_profile(vaapi, profile))
        return -1;
    if (!has_entrypoint(vaapi, profile, entrypoint))
        return -1;

    if (vaapi->profile != profile || vaapi->entrypoint != entrypoint) {
        if (vaapi->config_id)
            vaDestroyConfig(vaapi->display, vaapi->config_id);

        attrib.type = VAConfigAttribRTFormat;
        status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
                                       &attrib, 1);
        if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
            return -1;
        if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
            return -1;

        status = vaCreateConfig(vaapi->display, profile, entrypoint,
                                &attrib, 1, &config_id);
        if (!vaapi_check_status(status, "vaCreateConfig()"))
            return -1;
    }
    else
        config_id = vaapi->config_id;

    if (vaapi->picture_width != picture_width || vaapi->picture_height != picture_height) {
        if (vaapi->surface_id)
            vaDestroySurfaces(vaapi->display, &vaapi->surface_id, 1);

        status = vaCreateSurfaces(vaapi->display, picture_width, picture_height,
                                  VA_RT_FORMAT_YUV420, 1, &surface_id);
        if (!vaapi_check_status(status, "vaCreateSurfaces()"))
            return -1;

        if (vaapi->context_id)
            vaDestroyContext(vaapi->display, vaapi->context_id);

        status = vaCreateContext(vaapi->display, config_id,
                                 picture_width, picture_height,
                                 VA_PROGRESSIVE,
                                 &surface_id, 1,
                                 &context_id);
        if (!vaapi_check_status(status, "vaCreateContext()"))
            return -1;
    }
    else {
        context_id = vaapi->context_id;
        surface_id = vaapi->surface_id;
    }

    vaapi->config_id      = config_id;
    vaapi->context_id     = context_id;
    vaapi->surface_id     = surface_id;
    vaapi->profile        = profile;
    vaapi->entrypoint     = entrypoint;
    vaapi->picture_width  = picture_width;
    vaapi->picture_height = picture_height;
    return 0;
}
コード例 #19
0
ファイル: VAApiWriter.cpp プロジェクト: JandunCN/QMPlay2
bool VAApiWriter::HWAccellInit( int W, int H, const char *codec_name )
{
	VAProfile p = ( VAProfile )-1; //VAProfileNone
	if ( !qstrcmp( codec_name, "h264" ) )
	{
		if ( profileList.contains( VAProfileH264High ) )
			p = VAProfileH264High;
		else if ( profileList.contains( VAProfileH264Main ) )
			p = VAProfileH264Main;
		else if ( profileList.contains( VAProfileH264Baseline ) )
			p = VAProfileH264Baseline;
	}
	else if ( !qstrcmp( codec_name, "mpeg2video" ) )
	{
		if ( profileList.contains( VAProfileMPEG2Main ) )
			p = VAProfileMPEG2Main;
		else if ( profileList.contains( VAProfileMPEG2Simple ) )
			p = VAProfileMPEG2Simple;
	}
	else if ( !qstrcmp( codec_name, "mpeg4" ) )
	{
		if ( profileList.contains( VAProfileMPEG4Main ) )
			p = VAProfileMPEG4Main;
		else if ( profileList.contains( VAProfileMPEG4Simple ) )
			p = VAProfileMPEG4Simple;
	}
	else if ( !qstrcmp( codec_name, "vc1" ) )
	{
		if ( profileList.contains( VAProfileVC1Advanced ) )
			p = VAProfileVC1Advanced;
		else if ( profileList.contains( VAProfileVC1Main ) )
			p = VAProfileVC1Main;
		else if ( profileList.contains( VAProfileVC1Simple ) )
			p = VAProfileVC1Simple;
	}
	else if ( !qstrcmp( codec_name, "h263" ) && profileList.contains( VAProfileH263Baseline ) )
		p = VAProfileH263Baseline;

	if ( !ok || profile != p || outW != W || outH != H )
	{
		clr();

		profile = p;
		outW = W;
		outH = H;

		if ( !vaCreateSurfaces( surfaces, surfacesCount ) )
			return false;
		surfacesCreated = true;

		if ( !vaCreateConfigAndContext() )
			return false;

		for ( int i = 0 ; i < surfacesCount ; i++ )
			surfacesQueue.enqueue( surfaces[ i ] );


		unsigned numSubpicFmts = vaMaxNumSubpictureFormats( VADisp );
		VAImageFormat subpicFmtList[ numSubpicFmts ];
		unsigned subpic_flags[ numSubpicFmts ];
		if ( vaQuerySubpictureFormats( VADisp, subpicFmtList, subpic_flags, &numSubpicFmts ) == VA_STATUS_SUCCESS )
		{
			for ( unsigned i = 0 ; i < numSubpicFmts ; ++i )
				if ( !qstrncmp( ( const char * )&subpicFmtList[ i ].fourcc, "BGRA", 4 ) )
				{
					subpict_dest_is_screen_coord = subpic_flags[ i ] & VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD;
					rgbImgFmt = new VAImageFormat( subpicFmtList[ i ] );
					break;
				}
		}

		init_vpp();

		if ( isXvBA )
		{
			QWidget::destroy();
			QWidget::create();
		}

		ok = true;
	}
	else
	{
#ifdef HAVE_VPP
		forward_reference = VA_INVALID_SURFACE;
		vpp_second = false;
#endif
		if ( isVDPAU )
		{
			if ( context )
			{
				vaDestroyContext( VADisp, context );
				context = 0;
			}
			if ( config )
			{
				vaDestroyConfig( VADisp, config );
				config = 0;
			}
			if ( !vaCreateConfigAndContext() )
				return false;
		}
	}

	return ok;
}
コード例 #20
0
ファイル: vaapi.c プロジェクト: 42TheAnswerToLife/vlc
static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
                   const es_format_t *fmt, picture_sys_t *p_sys )
{
    if( pix_fmt != AV_PIX_FMT_VAAPI_VLD )
        return VLC_EGENERIC;

    (void) fmt;
    (void) p_sys;
#ifdef VLC_VA_BACKEND_XLIB
    if( !vlc_xlib_init( VLC_OBJECT(va) ) )
    {
        msg_Warn( va, "Ignoring VA-X11 API" );
        return VLC_EGENERIC;
    }
#endif

    VAProfile i_profile, *p_profiles_list;
    bool b_supported_profile = false;
    int i_profiles_nb = 0;
    unsigned count = 3;

    /* */
    switch( ctx->codec_id )
    {
    case AV_CODEC_ID_MPEG1VIDEO:
    case AV_CODEC_ID_MPEG2VIDEO:
        i_profile = VAProfileMPEG2Main;
        count = 4;
        break;
    case AV_CODEC_ID_MPEG4:
        i_profile = VAProfileMPEG4AdvancedSimple;
        break;
    case AV_CODEC_ID_WMV3:
        i_profile = VAProfileVC1Main;
        break;
    case AV_CODEC_ID_VC1:
        i_profile = VAProfileVC1Advanced;
        break;
    case AV_CODEC_ID_H264:
        i_profile = VAProfileH264High;
        count = 18;
        break;;
    default:
        return VLC_EGENERIC;
    }
    count += ctx->thread_count;

    vlc_va_sys_t *sys;
    void *mem;

    assert(popcount(sizeof (sys->surfaces)) == 1);
    if (unlikely(posix_memalign(&mem, sizeof (sys->surfaces), sizeof (*sys))))
       return VLC_ENOMEM;

    sys = mem;
    memset(sys, 0, sizeof (*sys));

    /* */
    sys->hw_ctx.display = NULL;
    sys->hw_ctx.config_id = VA_INVALID_ID;
    sys->hw_ctx.context_id = VA_INVALID_ID;
    sys->width = ctx->coded_width;
    sys->height = ctx->coded_height;
    sys->count = count;
    sys->available = (1 << sys->count) - 1;
    assert(count < sizeof (sys->available) * CHAR_BIT);
    assert(count * sizeof (sys->surfaces[0]) <= sizeof (sys->surfaces));

    /* Create a VA display */
#ifdef VLC_VA_BACKEND_XLIB
    sys->p_display_x11 = XOpenDisplay(NULL);
    if( !sys->p_display_x11 )
    {
        msg_Err( va, "Could not connect to X server" );
        goto error;
    }

    sys->hw_ctx.display = vaGetDisplay(sys->p_display_x11);
#endif
#ifdef VLC_VA_BACKEND_DRM
    sys->drm_fd = vlc_open("/dev/dri/card0", O_RDWR);
    if( sys->drm_fd == -1 )
    {
        msg_Err( va, "Could not access rendering device: %m" );
        goto error;
    }

    sys->hw_ctx.display = vaGetDisplayDRM(sys->drm_fd);
#endif
    if (sys->hw_ctx.display == NULL)
    {
        msg_Err( va, "Could not get a VAAPI device" );
        goto error;
    }

    int major, minor;
    if (vaInitialize(sys->hw_ctx.display, &major, &minor))
    {
        msg_Err( va, "Failed to initialize the VAAPI device" );
        goto error;
    }

    /* Check if the selected profile is supported */
    i_profiles_nb = vaMaxNumProfiles(sys->hw_ctx.display);
    p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) );
    if( !p_profiles_list )
        goto error;

    if (vaQueryConfigProfiles(sys->hw_ctx.display, p_profiles_list,
                              &i_profiles_nb) == VA_STATUS_SUCCESS)
    {
        for( int i = 0; i < i_profiles_nb; i++ )
        {
            if ( p_profiles_list[i] == i_profile )
            {
                b_supported_profile = true;
                break;
            }
        }
    }
    free( p_profiles_list );
    if ( !b_supported_profile )
    {
        msg_Dbg( va, "Codec and profile not supported by the hardware" );
        goto error;
    }

    /* Create a VA configuration */
    VAConfigAttrib attrib;
    memset( &attrib, 0, sizeof(attrib) );
    attrib.type = VAConfigAttribRTFormat;
    if (vaGetConfigAttributes(sys->hw_ctx.display, i_profile, VAEntrypointVLD,
                              &attrib, 1))
        goto error;

    /* Not sure what to do if not, I don't have a way to test */
    if( (attrib.value & VA_RT_FORMAT_YUV420) == 0 )
        goto error;
    if (vaCreateConfig(sys->hw_ctx.display, i_profile, VAEntrypointVLD,
                       &attrib, 1, &sys->hw_ctx.config_id))
    {
        sys->hw_ctx.config_id = VA_INVALID_ID;
        goto error;
    }

    /* Create surfaces */
    assert(ctx->coded_width > 0 && ctx->coded_height > 0);
    if (vaCreateSurfaces(sys->hw_ctx.display, VA_RT_FORMAT_YUV420,
                         ctx->coded_width, ctx->coded_height,
                         sys->surfaces, sys->count, NULL, 0))
    {
        goto error;
    }

    /* Create a context */
    if (vaCreateContext(sys->hw_ctx.display, sys->hw_ctx.config_id,
                        ctx->coded_width, ctx->coded_height, VA_PROGRESSIVE,
                        sys->surfaces, sys->count, &sys->hw_ctx.context_id))
    {
        sys->hw_ctx.context_id = VA_INVALID_ID;
        vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
        goto error;
    }

    if (FindFormat(sys))
        goto error;

    if (unlikely(CopyInitCache(&sys->image_cache, ctx->coded_width)))
        goto error;

    vlc_mutex_init(&sys->lock);

    msg_Dbg(va, "using %s image format 0x%08x",
            sys->do_derive ? "derive" : "get", sys->format.fourcc);

    ctx->hwaccel_context = &sys->hw_ctx;
    va->sys = sys;
    va->description = vaQueryVendorString(sys->hw_ctx.display);
    va->get = Get;
    va->release = Release;
    va->extract = Extract;
    return VLC_SUCCESS;

error:
    if (sys->hw_ctx.context_id != VA_INVALID_ID)
    {
        vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
        vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
    }
    if (sys->hw_ctx.config_id != VA_INVALID_ID)
        vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id);
    if (sys->hw_ctx.display != NULL)
        vaTerminate(sys->hw_ctx.display);
#ifdef VLC_VA_BACKEND_XLIB
    if( sys->p_display_x11 != NULL )
        XCloseDisplay( sys->p_display_x11 );
#endif
#ifdef VLC_VA_BACKEND_DRM
    if( sys->drm_fd != -1 )
        close( sys->drm_fd );
#endif
    free( sys );
    return VLC_EGENERIC;
}