예제 #1
0
파일: vda.c 프로젝트: brendonjustin/vlc
static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
                  int i_width, int i_height )
{

    vlc_va_vda_t *p_va = vlc_va_vda_Get( p_external );

    if( p_va->hw_ctx.width == i_width
        && p_va->hw_ctx.height == i_height
        && p_va->hw_ctx.decoder )
    {
        *pp_hw_ctx = &p_va->hw_ctx;
        *pi_chroma = p_va->i_chroma;
        return VLC_SUCCESS;
    }

    if( p_va->hw_ctx.decoder )
    {
        ff_vda_destroy_decoder( &p_va->hw_ctx );
        goto ok;
    }

    memset( &p_va->hw_ctx, 0, sizeof(p_va->hw_ctx) );
    p_va->hw_ctx.width = i_width;
    p_va->hw_ctx.height = i_height;
    p_va->hw_ctx.format = 'avc1';

    int i_pix_fmt = var_CreateGetInteger( p_va->p_log, "avcodec-vda-pix-fmt" );

    switch( i_pix_fmt )
    {
        case 1 :
            p_va->hw_ctx.cv_pix_fmt_type = kCVPixelFormatType_422YpCbCr8;
            p_va->i_chroma = VLC_CODEC_UYVY;
            break;
        case 0 :
        default :
            p_va->hw_ctx.cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8Planar;
            p_va->i_chroma = VLC_CODEC_I420;
            CopyInitCache( &p_va->image_cache, i_width );
    }

ok:
    /* Setup the ffmpeg hardware context */
    *pp_hw_ctx = &p_va->hw_ctx;
    *pi_chroma = p_va->i_chroma;

    /* create the decoder */
    int status = ff_vda_create_decoder( &p_va->hw_ctx,
                                        p_va->p_extradata,
                                        p_va->i_extradata );
    if( status )
    {
        msg_Err( p_va->p_log, "Failed to create the decoder : %i", status );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
예제 #2
0
static void DxCreateVideoConversion(vlc_va_dxva2_t *va)
{
    switch (va->render) {
    case MAKEFOURCC('N','V','1','2'):
    case MAKEFOURCC('I','M','C','3'):
        va->output = MAKEFOURCC('Y','V','1','2');
        break;
    default:
        va->output = va->render;
        break;
    }
    CopyInitCache(&va->surface_cache, va->surface_width);
}
예제 #3
0
파일: utils.c 프로젝트: jsharma44/vlc
/*****************************************************************************
 * Picture utility functions
 *****************************************************************************/
void ArchitectureSpecificCopyHooks( decoder_t *p_dec, int i_color_format,
                                    int i_slice_height, int i_src_stride,
                                    ArchitectureSpecificCopyData *p_architecture_specific )
{
    (void)i_slice_height;

#ifdef CAN_COMPILE_SSE2
    if( i_color_format == OMX_COLOR_FormatYUV420SemiPlanar && vlc_CPU_SSE2() )
    {
        copy_cache_t *p_surface_cache = malloc( sizeof(copy_cache_t) );
        if( !p_surface_cache || CopyInitCache( p_surface_cache, i_src_stride ) )
        {
            free( p_surface_cache );
            return;
        }
        p_architecture_specific->data = p_surface_cache;
        p_dec->fmt_out.i_codec = VLC_CODEC_YV12;
    }
#endif
}
예제 #4
0
파일: vaapi.c 프로젝트: repstd/modified_vlc
static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
                           int i_width, int i_height )
{
    assert( i_width > 0 && i_height > 0 );

    /* */
    p_va->p_surface = calloc( p_va->i_surface_count, sizeof(*p_va->p_surface) );
    if( !p_va->p_surface )
        return VLC_EGENERIC;
    p_va->image.image_id = VA_INVALID_ID;
    p_va->i_context_id   = VA_INVALID_ID;

    /* Create surfaces */
    VASurfaceID pi_surface_id[p_va->i_surface_count];
    if( vaCreateSurfaces( p_va->p_display, i_width, i_height, VA_RT_FORMAT_YUV420,
                          p_va->i_surface_count, pi_surface_id ) )
    {
        for( int i = 0; i < p_va->i_surface_count; i++ )
            p_va->p_surface[i].i_id = VA_INVALID_SURFACE;
        goto error;
    }

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

        p_surface->i_id = pi_surface_id[i];
        p_surface->i_refcount = 0;
        p_surface->i_order = 0;
    }

    /* Create a context */
    if( vaCreateContext( p_va->p_display, p_va->i_config_id,
                         i_width, i_height, VA_PROGRESSIVE,
                         pi_surface_id, p_va->i_surface_count, &p_va->i_context_id ) )
    {
        p_va->i_context_id = VA_INVALID_ID;
        goto error;
    }

    /* Find and create a supported image chroma */
    int i_fmt_count = vaMaxNumImageFormats( p_va->p_display );
    VAImageFormat *p_fmt = calloc( i_fmt_count, sizeof(*p_fmt) );
    if( !p_fmt )
        goto error;

    if( vaQueryImageFormats( p_va->p_display, p_fmt, &i_fmt_count ) )
    {
        free( p_fmt );
        goto error;
    }

    VAImage testImage;
    if(vaDeriveImage(p_va->p_display, pi_surface_id[0], &testImage) == VA_STATUS_SUCCESS)
    {
        p_va->b_supports_derive = true;
        vaDestroyImage(p_va->p_display, testImage.image_id);
    }

    vlc_fourcc_t  i_chroma = 0;
    VAImageFormat fmt;
    for( int i = 0; i < i_fmt_count; i++ )
    {
        if( p_fmt[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) ||
            p_fmt[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ||
            p_fmt[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) )
        {
            if( vaCreateImage(  p_va->p_display, &p_fmt[i], i_width, i_height, &p_va->image ) )
            {
                p_va->image.image_id = VA_INVALID_ID;
                continue;
            }
            /* Validate that vaGetImage works with this format */
            if( vaGetImage( p_va->p_display, pi_surface_id[0],
                            0, 0, i_width, i_height,
                            p_va->image.image_id) )
            {
                vaDestroyImage( p_va->p_display, p_va->image.image_id );
                p_va->image.image_id = VA_INVALID_ID;
                continue;
            }

            i_chroma = VLC_CODEC_YV12;
            fmt = p_fmt[i];
            break;
        }
    }
    free( p_fmt );
    if( !i_chroma )
        goto error;
    *pi_chroma = i_chroma;

    if(p_va->b_supports_derive)
    {
        vaDestroyImage( p_va->p_display, p_va->image.image_id );
        p_va->image.image_id = VA_INVALID_ID;
    }

    if( unlikely(CopyInitCache( &p_va->image_cache, i_width )) )
        goto error;

    /* Setup the ffmpeg hardware context */
    *pp_hw_ctx = &p_va->hw_ctx;

    memset( &p_va->hw_ctx, 0, sizeof(p_va->hw_ctx) );
    p_va->hw_ctx.display    = p_va->p_display;
    p_va->hw_ctx.config_id  = p_va->i_config_id;
    p_va->hw_ctx.context_id = p_va->i_context_id;

    /* */
    p_va->i_surface_chroma = i_chroma;
    p_va->i_surface_width = i_width;
    p_va->i_surface_height = i_height;
    return VLC_SUCCESS;

error:
    DestroySurfaces( p_va );
    return VLC_EGENERIC;
}
예제 #5
0
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;
}
예제 #6
0
파일: vda.c 프로젝트: Aakash-729/vlc
static int Setup( vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *pi_chroma )
{
    vlc_va_vda_t *p_vda = vlc_va_vda_Get( va );

    if( p_vda->hw_ctx.width == avctx->coded_width
       && p_vda->hw_ctx.height == avctx->coded_height
       && p_vda->hw_ctx.decoder )
    {
        avctx->hwaccel_context = &p_vda->hw_ctx;
        *pi_chroma = p_vda->i_chroma;
        return VLC_SUCCESS;
    }

    if( p_vda->hw_ctx.decoder )
    {
        ff_vda_destroy_decoder( &p_vda->hw_ctx );
        goto ok;
    }

    memset( &p_vda->hw_ctx, 0, sizeof(p_vda->hw_ctx) );
    p_vda->hw_ctx.format = 'avc1';
    p_vda->hw_ctx.use_ref_buffer = 1;

    int i_pix_fmt = var_CreateGetInteger( va, "avcodec-vda-pix-fmt" );

    switch( i_pix_fmt )
    {
        case 1 :
            p_vda->hw_ctx.cv_pix_fmt_type = kCVPixelFormatType_422YpCbCr8;
            p_vda->i_chroma = VLC_CODEC_UYVY;
            msg_Dbg(va, "using pixel format 422YpCbCr8");
            break;
        case 0 :
        default :
            p_vda->hw_ctx.cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8Planar;
            p_vda->i_chroma = VLC_CODEC_I420;
            CopyInitCache( &p_vda->image_cache, avctx->coded_width );
            msg_Dbg(va, "using pixel format 420YpCbCr8Planar");
    }

ok:
    /* Setup the libavcodec hardware context */
    avctx->hwaccel_context = &p_vda->hw_ctx;
    *pi_chroma = p_vda->i_chroma;

    p_vda->hw_ctx.width = avctx->coded_width;
    p_vda->hw_ctx.height = avctx->coded_height;

    /* create the decoder */
    int status = ff_vda_create_decoder( &p_vda->hw_ctx,
                                       p_vda->p_extradata,
                                       p_vda->i_extradata );
    if( status )
    {
        msg_Err( va, "Failed to create decoder: %i", status );
        return VLC_EGENERIC;
    }
    else
        msg_Dbg( va, "VDA decoder created");

    return VLC_SUCCESS;
}