enum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat(struct AVCodecContext * avctx, const AVPixelFormat * fmt) { ICallbackHWAccel *cb = static_cast<ICallbackHWAccel*>(avctx->opaque); CDVDVideoCodecFFmpeg* ctx = dynamic_cast<CDVDVideoCodecFFmpeg*>(cb); const char* pixFmtName = av_get_pix_fmt_name(*fmt); ctx->m_processInfo.SetVideoDimensions(avctx->coded_width, avctx->coded_height); // if frame threading is enabled hw accel is not allowed // 2nd condition: // fix an ffmpeg issue here, it calls us with an invalid profile // then a 2nd call with a valid one if(ctx->m_decoderState != STATE_HW_SINGLE || (avctx->codec_id == AV_CODEC_ID_VC1 && avctx->profile == FF_PROFILE_UNKNOWN)) { AVPixelFormat defaultFmt = avcodec_default_get_format(avctx, fmt); pixFmtName = av_get_pix_fmt_name(defaultFmt); ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->m_processInfo.SetSwDeinterlacingMethods(); return defaultFmt; } // hardware decoder de-selected, restore standard ffmpeg if (ctx->HasHardware()) { ctx->SetHardware(nullptr); avctx->get_buffer2 = avcodec_default_get_buffer2; avctx->slice_flags = 0; av_buffer_unref(&avctx->hw_frames_ctx); } const AVPixelFormat * cur = fmt; while (*cur != AV_PIX_FMT_NONE) { pixFmtName = av_get_pix_fmt_name(*cur); auto hwaccels = CDVDFactoryCodec::GetHWAccels(); for (auto &hwaccel : hwaccels) { IHardwareDecoder *pDecoder(CDVDFactoryCodec::CreateVideoCodecHWAccel(hwaccel, ctx->m_hints, ctx->m_processInfo, *cur)); if (pDecoder) { if (pDecoder->Open(avctx, ctx->m_pCodecContext, *cur)) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->SetHardware(pDecoder); return *cur; } } SAFE_RELEASE(pDecoder); } cur++; } ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->m_decoderState = STATE_HW_FAILED; return avcodec_default_get_format(avctx, fmt); }
static AVPixelFormat getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats) { auto accel = static_cast<HardwareAccel*>(codecCtx->opaque); if (!accel) { // invalid state, try to recover return avcodec_default_get_format(codecCtx, formats); } for (int i = 0; formats[i] != AV_PIX_FMT_NONE; i++) { if (formats[i] == accel->format()) { accel->setWidth(codecCtx->coded_width); accel->setHeight(codecCtx->coded_height); accel->setProfile(codecCtx->profile); accel->setCodecCtx(codecCtx); if (accel->init()) return accel->format(); break; } } accel->fail(true); RING_WARN("Falling back to software decoding"); codecCtx->get_format = avcodec_default_get_format; codecCtx->get_buffer2 = avcodec_default_get_buffer2; for (int i = 0; formats[i] != AV_PIX_FMT_NONE; i++) { auto desc = av_pix_fmt_desc_get(formats[i]); if (desc && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { return formats[i]; } } return AV_PIX_FMT_NONE; }
AVPixelFormat VideoDecoderFFmpegHWPrivate::getFormat(struct AVCodecContext *p_context, const AVPixelFormat *pi_fmt) { bool can_hwaccel = false; for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(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; qDebug("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; for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(NONE); i++) { if (vaPixelFormat() != pi_fmt[i]) continue; /* We try to call setup when possible to detect errors when possible (later is too late) */ if (p_context->width > 0 && p_context->height > 0 && !setup(p_context)) { qWarning("acceleration setup failure"); break; } qDebug("Using %s for hardware decoding.", qPrintable(description)); p_context->draw_horiz_band = NULL; //?? return pi_fmt[i]; } close(); end: qWarning("hardware acceleration is not available" ); /* Fallback to default behaviour */ return avcodec_default_get_format(p_context, pi_fmt); }
AVPixelFormat VideoDecoderFFmpegHWPrivate::getFormat(struct AVCodecContext *p_context, const AVPixelFormat *pi_fmt) { bool can_hwaccel = false; for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(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; qDebug("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 0 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; #endif for (size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++) { if (vaPixelFormat() != 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 && !setup(p_context)) { qWarning("acceleration setup failure"); break; } qDebug("Using %s for hardware decoding.", qPrintable(description)); /* FIXME this will disable direct rendering * even if a new pixel format is renegotiated */ //p_sys->b_direct_rendering = false; p_context->draw_horiz_band = NULL; return pi_fmt[i]; } close(); //vlc_va_Delete(p_va); end: qWarning("acceleration not available" ); /* Fallback to default behaviour */ return avcodec_default_get_format(p_context, pi_fmt); }
enum PixelFormat hb_ffmpeg_get_format( AVCodecContext *p_context, const enum PixelFormat *pi_fmt ) { int i; for( i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++ ) { hb_log( "dxva2:Available decoder output format %d (%s)", pi_fmt[i], hb_get_pix_fmt_name(pi_fmt[i]) ? : "Unknown" ); if( pi_fmt[i] == AV_PIX_FMT_DXVA2_VLD ) { return pi_fmt[i]; } } return avcodec_default_get_format( p_context, pi_fmt ); }
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 ) { VaDelete( 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", [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 ) { msg_Dbg( p_dec, "Trying VA API" ); p_sys->p_va = VaNew( p_sys->i_codec_id ); if( p_sys->p_va ) { /* FIXME this will disabled direct rendering * even if a new pixel format is renegociated * * FIXME Try to call VaSetup when possible * to detect errors when possible (later is too late) */ p_sys->b_direct_rendering = false; p_sys->p_context->draw_horiz_band = NULL; return pi_fmt[i]; } msg_Warn( p_dec, "Failed to open VA API" ); } } /* Fallback to default behaviour */ return avcodec_default_get_format( p_codec, pi_fmt ); }
static enum PixelFormat libav_get_format(struct AVCodecContext *ctx, const enum PixelFormat *fmt) { media_codec_t *mc = ctx->opaque; if(mc->close != NULL) { mc->close(mc); mc->close = NULL; } #if ENABLE_VDPAU if(!vdpau_init_libav_decode(mc, ctx)) { return AV_PIX_FMT_VDPAU; } #endif mc->get_buffer2 = &avcodec_default_get_buffer2; return avcodec_default_get_format(ctx, fmt); }
enum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx , const AVPixelFormat * fmt ) { CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; // if frame threading is enabled hw accel is not allowed if(ctx->m_decoderState != STATE_HW_SINGLE) { return avcodec_default_get_format(avctx, fmt); } // fix an ffmpeg issue here, it calls us with an invalid profile // then a 2nd call with a valid one if (avctx->codec_id == AV_CODEC_ID_VC1 && avctx->profile == FF_PROFILE_UNKNOWN) { return avcodec_default_get_format(avctx, fmt); } // hardware decoder de-selected, restore standard ffmpeg if (ctx->GetHardware()) { ctx->SetHardware(NULL); avctx->get_buffer2 = avcodec_default_get_buffer2; avctx->slice_flags = 0; avctx->hwaccel_context = 0; } const AVPixelFormat * cur = fmt; while(*cur != AV_PIX_FMT_NONE) { #ifdef HAVE_LIBVDPAU if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU)) { CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height); VDPAU::CDecoder* vdp = new VDPAU::CDecoder(); if(vdp->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(vdp); return *cur; } else vdp->Release(); } #endif #ifdef HAS_DX if(DXVA::CDecoder::Supports(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2) && !ctx->m_hints.dvd && !ctx->m_hints.stills) { CLog::Log(LOGNOTICE, "CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)", avctx->width, avctx->height); DXVA::CDecoder* dec = new DXVA::CDecoder(); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef HAVE_LIBVA // mpeg4 vaapi decoding is disabled if(*cur == AV_PIX_FMT_VAAPI_VLD && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI)) { VAAPI::CDecoder* dec = new VAAPI::CDecoder(); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount) == true) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef TARGET_DARWIN if (*cur == AV_PIX_FMT_VIDEOTOOLBOX && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVTB)) { VTB::CDecoder* dec = new VTB::CDecoder(); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef HAS_MMAL if (*cur == AV_PIX_FMT_YUV420P) { MMAL::CDecoder* dec = new MMAL::CDecoder(); ctx->m_pCodecContext->hwaccel_context = (void *)ctx->m_options.m_opaque_pointer; if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif cur++; } ctx->m_decoderState = STATE_HW_FAILED; return avcodec_default_get_format(avctx, 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; 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 ); }