int VideoDecoder::GetAVBuffer(AVCodecContext *Context, AVFrame *Frame) { VideoFrame *frame = m_videoParent->GetBuffers()->GetFrameForDecoding(); if (!frame) return -1; if (Context->width != frame->m_rawWidth || Context->height != frame->m_rawHeight || Context->pix_fmt != frame->m_pixelFormat) LOG(VB_GENERAL, LOG_ERR, "Frame format changed"); // start frame initalisation Frame->opaque = frame; Frame->type = FF_BUFFER_TYPE_USER; Frame->pkt_pts = Context->pkt ? Context->pkt->pts : AV_NOPTS_VALUE; Frame->pkt_dts = Context->pkt ? Context->pkt->dts : AV_NOPTS_VALUE; Frame->width = frame->m_rawWidth; Frame->height = frame->m_rawHeight; Frame->format = frame->m_pixelFormat; Frame->sample_aspect_ratio = Context->sample_aspect_ratio; // initialise hardware context // FIXME this needs a failure mode so that we don't always fallback to a software frame bool initialised = false; AccelerationFactory* factory = AccelerationFactory::GetAccelerationFactory(); for ( ; factory; factory = factory->NextFactory()) { if (factory->InitialiseBuffer(Context, Frame, frame)) { initialised = true; break; } } // or fallback to software decoding if (!initialised) { frame->InitialiseBuffer(); for (int i = 0; i < 4; i++) { Frame->data[i] = frame->m_buffer + frame->m_offsets[i]; Frame->base[i] = Frame->data[i]; Frame->linesize[i] = frame->m_pitches[i]; } } // finish frame initialisation Frame->extended_data = Frame->data; return 0; }