Пример #1
0
/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
 * This function is called when the thread ends after a successful
 * initialization.
 *****************************************************************************/
void EndVideoDec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */
    if( p_sys->p_context->codec )
        avcodec_flush_buffers( p_sys->p_context );

    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );

    if( p_sys->p_va )
    {
        vlc_va_Delete( p_sys->p_va );
        p_sys->p_va = NULL;
    }
}
Пример #2
0
Файл: video.c Проект: bobwxb/vlc
/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
 * This function is called when the thread ends after a successful
 * initialization.
 *****************************************************************************/
void EndVideoDec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    post_mt( p_sys );

    /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */
    if( p_sys->p_context->codec )
        avcodec_flush_buffers( p_sys->p_context );

    wait_mt( p_sys );

    ffmpeg_CloseCodec( p_dec );

    if( p_sys->p_va )
        vlc_va_Delete( p_sys->p_va, p_sys->p_context );

    vlc_sem_destroy( &p_sys->sem_mt );
}
Пример #3
0
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    vlc_va_t *p_va = p_sys->p_va;

    if( p_va != NULL )
        vlc_va_Delete( p_va );

    /* Enumerate available formats */
    bool can_hwaccel = false;
    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        goto end;

    /* Profile and level information is needed now.
     * TODO: avoid code duplication with avcodec.c */
    if( p_context->profile != FF_PROFILE_UNKNOWN)
        p_dec->fmt_in.i_profile = p_context->profile;
    if( p_context->level != FF_LEVEL_UNKNOWN)
        p_dec->fmt_in.i_level = p_context->level;

    p_va = vlc_va_New( VLC_OBJECT(p_dec), p_context, &p_dec->fmt_in );
    if( p_va == NULL )
        goto end;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        if( p_va->pix_fmt != pi_fmt[i] )
            continue;

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if( p_context->width > 0 && p_context->height > 0
         && vlc_va_Setup( p_va, &p_context->hwaccel_context,
                          &p_dec->fmt_out.video.i_chroma,
                          p_context->width, p_context->height ) )
        {
            msg_Err( p_dec, "acceleration setup failure" );
            break;
        }

        if( p_va->description )
            msg_Info( p_dec, "Using %s for hardware decoding.",
                      p_va->description );

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        p_sys->b_direct_rendering = false;
        p_sys->p_va = p_va;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    vlc_va_Delete( p_va );

end:
    /* Fallback to default behaviour */
    p_sys->p_va = NULL;
    return avcodec_default_get_format( p_context, pi_fmt );
}
Пример #4
0
Файл: video.c Проект: bobwxb/vlc
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    if (p_sys->p_va != NULL)
    {
        vlc_va_Delete(p_sys->p_va, p_context);
        p_sys->p_va = NULL;
    }

    /* Enumerate available formats */
    enum PixelFormat swfmt = avcodec_default_get_format(p_context, pi_fmt);
    bool can_hwaccel = false;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        return swfmt;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        enum PixelFormat hwfmt = pi_fmt[i];

        p_dec->fmt_out.video.i_chroma = vlc_va_GetChroma(hwfmt, swfmt);
        if (p_dec->fmt_out.video.i_chroma == 0)
            continue; /* Unknown brand of hardware acceleration */
        if (lavc_UpdateVideoFormat(p_dec, p_context, true))
            continue; /* Unsupported brand of hardware acceleration */

        vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), p_context, hwfmt,
                                  &p_dec->fmt_in);
        if (va == NULL)
            continue; /* Unsupported codec profile or such */

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if( p_context->width > 0 && p_context->height > 0
         && vlc_va_Setup(va, p_context, &p_dec->fmt_out.video.i_chroma))
        {
            msg_Err( p_dec, "acceleration setup failure" );
            vlc_va_Delete(va, p_context);
            continue;
        }

        if (va->description != NULL)
            msg_Info(p_dec, "Using %s for hardware decoding", va->description);

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        p_sys->b_direct_rendering = false;
        p_sys->p_va = va;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    /* Fallback to default behaviour */
    return swfmt;
}
Пример #5
0
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_codec,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_codec->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_sys->p_va )
    {
        vlc_va_Delete( p_sys->p_va );
        p_sys->p_va = NULL;
    }

    /* Try too look for a supported hw acceleration */
    for( int i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        static const char *ppsz_name[PIX_FMT_NB] = {
            [PIX_FMT_VDPAU_H264] = "PIX_FMT_VDPAU_H264",
            [PIX_FMT_VAAPI_IDCT] = "PIX_FMT_VAAPI_IDCT",
            [PIX_FMT_VAAPI_VLD] = "PIX_FMT_VAAPI_VLD",
            [PIX_FMT_VAAPI_MOCO] = "PIX_FMT_VAAPI_MOCO",
#ifdef HAVE_AVCODEC_DXVA2
            [PIX_FMT_DXVA2_VLD] = "PIX_FMT_DXVA2_VLD",
#endif
            [PIX_FMT_YUYV422] = "PIX_FMT_YUYV422",
            [PIX_FMT_YUV420P] = "PIX_FMT_YUV420P",
        };
        msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i], ppsz_name[pi_fmt[i]] ?: "Unknown" );

        /* Only VLD supported */
        if( pi_fmt[i] == PIX_FMT_VAAPI_VLD )
        {
#ifdef HAVE_AVCODEC_VAAPI
            msg_Dbg( p_dec, "Trying VA API" );
            p_sys->p_va = vlc_va_NewVaapi( p_sys->i_codec_id );
            if( !p_sys->p_va )
                msg_Warn( p_dec, "Failed to open VA API" );
#else
            continue;
#endif
        }
#ifdef HAVE_AVCODEC_DXVA2
        if( pi_fmt[i] == PIX_FMT_DXVA2_VLD )
        {
            msg_Dbg( p_dec, "Trying DXVA2" );
            p_sys->p_va = vlc_va_NewDxva2( VLC_OBJECT(p_dec), p_sys->i_codec_id );
            if( !p_sys->p_va )
                msg_Warn( p_dec, "Failed to open DXVA2" );
        }
#endif

        if( p_sys->p_va &&
            p_sys->p_context->width > 0 && p_sys->p_context->height > 0 )
        {
            /* We try to call vlc_va_Setup when possible to detect errors when
             * possible (later is too late) */
            if( vlc_va_Setup( p_sys->p_va,
                              &p_sys->p_context->hwaccel_context,
                              &p_dec->fmt_out.video.i_chroma,
                              p_sys->p_context->width, p_sys->p_context->height ) )
            {
                msg_Err( p_dec, "vlc_va_Setup failed" );
                vlc_va_Delete( p_sys->p_va );
                p_sys->p_va = NULL;
            }
        }

        if( p_sys->p_va )
        {
            if( p_sys->p_va->description )
                msg_Info( p_dec, "Using %s for hardware decoding.", p_sys->p_va->description );

            /* FIXME this will disabled direct rendering
             * even if a new pixel format is renegociated
             */
            p_sys->b_direct_rendering = false;
            p_sys->p_context->draw_horiz_band = NULL;
            return pi_fmt[i];
        }
    }

    /* Fallback to default behaviour */
    return avcodec_default_get_format( p_codec, pi_fmt );
}