bool CVDPAU::ConfigOutputMethod(AVCodecContext *avctx, AVFrame *pFrame) { VdpStatus vdp_st; if (m_vdpauOutputMethod == OUTPUT_PIXMAP) return true; FiniOutputMethod(); MakePixmap(avctx->width,avctx->height); vdp_st = vdp_presentation_queue_target_create_x11(vdp_device, m_Pixmap, //x_window, &vdp_flip_target); if (CheckStatus(vdp_st, __LINE__)) return false; vdp_st = vdp_presentation_queue_create(vdp_device, vdp_flip_target, &vdp_flip_queue); if (CheckStatus(vdp_st, __LINE__)) return false; totalAvailableOutputSurfaces = 0; int tmpMaxOutputSurfaces = NUM_OUTPUT_SURFACES; if (vid_width == FULLHD_WIDTH) tmpMaxOutputSurfaces = NUM_OUTPUT_SURFACES_FOR_FULLHD; // Creation of outputSurfaces for (int i = 0; i < NUM_OUTPUT_SURFACES && i < tmpMaxOutputSurfaces; i++) { vdp_st = vdp_output_surface_create(vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, OutWidth, OutHeight, &outputSurfaces[i]); if (CheckStatus(vdp_st, __LINE__)) return false; totalAvailableOutputSurfaces++; } CLog::Log(LOGNOTICE, " (VDPAU) Total Output Surfaces Available: %i of a max (tmp: %i const: %i)", totalAvailableOutputSurfaces, tmpMaxOutputSurfaces, NUM_OUTPUT_SURFACES); surfaceNum = presentSurfaceNum = 0; outputSurface = presentSurface = VDP_INVALID_HANDLE; videoMixer = VDP_INVALID_HANDLE; m_vdpauOutputMethod = OUTPUT_PIXMAP; return true; }
bool CVDPAU::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces) { if(avctx->width == 0 || avctx->height == 0) { CLog::Log(LOGWARNING,"(VDPAU) no width/height available, can't init"); return false; } if (!dl_handle) { dl_handle = dlopen("libvdpau.so.1", RTLD_LAZY); if (!dl_handle) { const char* error = dlerror(); if (!error) error = "dlerror() returned NULL"; CLog::Log(LOGNOTICE,"(VDPAU) Unable to get handle to libvdpau: %s", error); //g_application.m_guiDialogKaiToast.QueueNotification(CGUIDialogKaiToast::Error, "VDPAU", error, 10000); return false; } } InitVDPAUProcs(); if (vdp_device != VDP_INVALID_HANDLE) { SpewHardwareAvailable(); VdpDecoderProfile profile = 0; if(avctx->codec_id == CODEC_ID_H264) profile = VDP_DECODER_PROFILE_H264_HIGH; #ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP else if(avctx->codec_id == CODEC_ID_MPEG4) profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; #endif if(profile) { if (!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->width)) CLog::Log(LOGWARNING,"(VDPAU) width %i might not be supported because of hardware bug", avctx->width); /* attempt to create a decoder with this width/height, some sizes are not supported by hw */ VdpStatus vdp_st; vdp_st = vdp_decoder_create(vdp_device, profile, avctx->width, avctx->height, 5, &decoder); if(vdp_st != VDP_STATUS_OK) { CLog::Log(LOGERROR, " (VDPAU) Error: %s(%d) checking for decoder support\n", vdp_get_error_string(vdp_st), vdp_st); FiniVDPAUProcs(); return false; } vdp_decoder_destroy(decoder); CheckStatus(vdp_st, __LINE__); } InitCSCMatrix(avctx->height); MakePixmap(avctx->width,avctx->height); /* finally setup ffmpeg */ avctx->get_buffer = CVDPAU::FFGetBuffer; avctx->release_buffer = CVDPAU::FFReleaseBuffer; avctx->draw_horiz_band = CVDPAU::FFDrawSlice; avctx->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; return true; } return false; }