bool CVDPAU::ConfigVDPAU(AVCodecContext* avctx, int ref_frames) { FiniVDPAUOutput(); VdpStatus vdp_st; VdpDecoderProfile vdp_decoder_profile; vid_width = avctx->width; vid_height = avctx->height; surface_width = avctx->coded_width; surface_height = avctx->coded_height; past[1] = past[0] = current = future = NULL; CLog::Log(LOGNOTICE, " (VDPAU) screenWidth:%i vidWidth:%i surfaceWidth:%i",OutWidth,vid_width,surface_width); CLog::Log(LOGNOTICE, " (VDPAU) screenHeight:%i vidHeight:%i surfaceHeight:%i",OutHeight,vid_height,surface_height); ReadFormatOf(avctx->pix_fmt, vdp_decoder_profile, vdp_chroma_type); if(avctx->pix_fmt == PIX_FMT_VDPAU_H264) { max_references = ref_frames; if (max_references > 16) max_references = 16; if (max_references < 5) max_references = 5; } else max_references = 2; vdp_st = vdp_decoder_create(vdp_device, vdp_decoder_profile, surface_width, surface_height, max_references, &decoder); if (CheckStatus(vdp_st, __LINE__)) return false; m_vdpauOutputMethod = OUTPUT_NONE; vdpauConfigured = true; return true; }
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; }
bool CVDPAU::ConfigVDPAU(AVCodecContext* avctx, int ref_frames) { FiniVDPAUOutput(); VdpStatus vdp_st; VdpDecoderProfile vdp_decoder_profile; vid_width = avctx->width; vid_height = avctx->height; past[1] = past[0] = current = future = NULL; CLog::Log(LOGNOTICE, " (VDPAU) screenWidth:%i vidWidth:%i",OutWidth,vid_width); CLog::Log(LOGNOTICE, " (VDPAU) screenHeight:%i vidHeight:%i",OutHeight,vid_height); ReadFormatOf(avctx->pix_fmt, vdp_decoder_profile, vdp_chroma_type); if(avctx->pix_fmt == PIX_FMT_VDPAU_H264) { max_references = ref_frames; if (max_references > 16) max_references = 16; if (max_references < 5) max_references = 5; } else max_references = 2; vdp_st = vdp_decoder_create(vdp_device, vdp_decoder_profile, vid_width, vid_height, max_references, &decoder); CHECK_VDPAU_RETURN(vdp_st, false); vdp_st = vdp_presentation_queue_target_create_x11(vdp_device, m_Pixmap, //x_window, &vdp_flip_target); CHECK_VDPAU_RETURN(vdp_st, false); vdp_st = vdp_presentation_queue_create(vdp_device, vdp_flip_target, &vdp_flip_queue); CHECK_VDPAU_RETURN(vdp_st, 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]); CHECK_VDPAU_RETURN(vdp_st, 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 = outputSurfaces[surfaceNum]; vdpauConfigured = true; return true; }