enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx , const PixelFormat * fmt ) { CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; if(!ctx->IsHardwareAllowed()) return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt); const PixelFormat * cur = fmt; while(*cur != PIX_FMT_NONE) { #ifdef HAVE_LIBVDPAU if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("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, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(vdp); return *cur; } else vdp->Release(); } #endif #ifdef HAS_DX if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2")) { DXVA::CDecoder* dec = new DXVA::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef HAVE_LIBVA // mpeg4 vaapi decoding is disabled if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi") && (avctx->codec_id != AV_CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) { if (ctx->GetHardware() != NULL) { ctx->SetHardware(NULL); } VAAPI::CDecoder* dec = new VAAPI::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef TARGET_DARWIN_OSX if (*cur == AV_PIX_FMT_VDA_VLD && CSettings::Get().GetBool("videoplayer.usevda")) { VDA::CDecoder* dec = new VDA::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif cur++; } return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, 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_OSX if (*cur == AV_PIX_FMT_VDA && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDA) && g_advancedSettings.m_useFfmpegVda) { VDA::CDecoder* dec = new VDA::CDecoder(); 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); }
enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx , const PixelFormat * fmt ) { CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; // if frame threading is enabled hw accel is not allowed if((EDECODEMETHOD) CSettings::Get().GetInt("videoplayer.decodingmethod") != VS_DECODEMETHOD_HARDWARE || !ctx->IsHardwareAllowed()) return avcodec_default_get_format(avctx, fmt); const PixelFormat * cur = fmt; while(*cur != PIX_FMT_NONE) { #ifdef HAVE_LIBVDPAU if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("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, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(vdp); return *cur; } else vdp->Release(); } #endif #ifdef HAS_DX if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2")) { CLog::Log(LOGNOTICE, "CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)", avctx->width, avctx->height); DXVA::CDecoder* dec = new DXVA::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef HAVE_LIBVA // mpeg4 vaapi decoding is disabled if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi")) { VAAPI::CDecoder* dec = new VAAPI::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef TARGET_DARWIN_OSX if (*cur == AV_PIX_FMT_VDA && CSettings::Get().GetBool("videoplayer.usevda") && g_advancedSettings.m_useFfmpegVda) { VDA::CDecoder* dec = new VDA::CDecoder(); if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount)) { ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif cur++; } // 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; } return avcodec_default_get_format(avctx, fmt); }
enum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat(struct AVCodecContext * avctx, const AVPixelFormat * fmt) { CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; 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->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) { pixFmtName = av_get_pix_fmt_name(*cur); #ifdef HAVE_LIBVDPAU if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU)) { CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height); VDPAU::CDecoder* vdp = new VDPAU::CDecoder(ctx->m_processInfo); if(vdp->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->SetHardware(vdp); return *cur; } else vdp->Release(); } #endif #ifdef HAS_DX if(DXVA::CDecoder::Supports(*cur) && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2)) { CLog::Log(LOGNOTICE, "CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)", avctx->width, avctx->height); DXVA::CDecoder* dec = new DXVA::CDecoder(ctx->m_processInfo); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef HAVE_LIBVA // mpeg4 vaapi decoding is disabled if(*cur == AV_PIX_FMT_VAAPI_VLD && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI)) { VAAPI::CDecoder* dec = new VAAPI::CDecoder(ctx->m_processInfo); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount) == true) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif #ifdef TARGET_DARWIN if (*cur == AV_PIX_FMT_VIDEOTOOLBOX && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVTB)) { VTB::CDecoder* dec = new VTB::CDecoder(ctx->m_processInfo); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); 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_processInfo, ctx->m_hints); if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount)) { ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->SetHardware(dec); return *cur; } else dec->Release(); } #endif cur++; } ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : ""); ctx->m_processInfo.SetSwDeinterlacingMethods(); ctx->m_decoderState = STATE_HW_FAILED; return avcodec_default_get_format(avctx, fmt); }
int CVDPAU::FFGetBuffer(AVCodecContext *avctx, AVFrame *pic) { //CLog::Log(LOGNOTICE,"%s",__FUNCTION__); CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque; CVDPAU* vdp = (CVDPAU*)ctx->GetHardware(); struct pictureAge* pA = &vdp->picAge; // while we are waiting to recover we can't do anything if(vdp->recover) { CLog::Log(LOGWARNING, "CVDPAU::FFGetBuffer - returning due to awaiting recovery"); return -1; } vdpau_render_state * render = NULL; // find unused surface for(unsigned int i = 0; i < vdp->m_videoSurfaces.size(); i++) { if(!(vdp->m_videoSurfaces[i]->state & (FF_VDPAU_STATE_USED_FOR_REFERENCE | FF_VDPAU_STATE_USED_FOR_RENDER))) { render = vdp->m_videoSurfaces[i]; render->state = 0; break; } } VdpStatus vdp_st = VDP_STATUS_ERROR; if (render == NULL) { // create a new surface VdpDecoderProfile profile; ReadFormatOf(avctx->pix_fmt, profile, vdp->vdp_chroma_type); render = (vdpau_render_state*)calloc(sizeof(vdpau_render_state), 1); vdp_st = vdp->vdp_video_surface_create(vdp->vdp_device, vdp->vdp_chroma_type, avctx->width, avctx->height, &render->surface); vdp->CheckStatus(vdp_st, __LINE__); if (vdp_st != VDP_STATUS_OK) { free(render); CLog::Log(LOGERROR, "CVDPAU::FFGetBuffer - No Video surface available could be created"); return -1; } vdp->m_videoSurfaces.push_back(render); } if (render == NULL) return -1; pic->data[1] = pic->data[2] = NULL; pic->data[0]= (uint8_t*)render; pic->linesize[0] = pic->linesize[1] = pic->linesize[2] = 0; if(pic->reference) { pic->age = pA->ip_age[0]; pA->ip_age[0]= pA->ip_age[1]+1; pA->ip_age[1]= 1; pA->b_age++; } else { pic->age = pA->b_age; pA->ip_age[0]++; pA->ip_age[1]++; pA->b_age = 1; } pic->type= FF_BUFFER_TYPE_USER; render->state |= FF_VDPAU_STATE_USED_FOR_REFERENCE; pic->reordered_opaque= avctx->reordered_opaque; return 0; }