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