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