bool VideoDecoderThread::work() { if (m_pDecoder->isEOF(SS_VIDEO)) { if (!m_pDecoder->getVideoInfo().m_bHasAudio) { m_pDecoder->seek(0); } else { // TODO: Replace this with waitForMessage() msleep(10); } } else { ScopeTimer timer(DecoderProfilingZone); vdpau_render_state* pRenderState = 0; FrameAvailableCode frameAvailable; vector<BitmapPtr> pBmps; bool usesVDPAU = m_pDecoder->getVideoInfo().m_bUsesVDPAU; if (usesVDPAU) { #ifdef AVG_ENABLE_VDPAU frameAvailable = m_pDecoder->renderToVDPAU(&pRenderState); #else frameAvailable = FA_NEW_FRAME; // Never executed - silences compiler warning. #endif } else { IntPoint size = m_pDecoder->getSize(); IntPoint halfSize(size.x/2, size.y/2); PixelFormat pf = m_pDecoder->getPixelFormat(); if (pixelFormatIsPlanar(pf)) { pBmps.push_back(getBmp(m_pBmpQ, size, I8)); pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8)); pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8)); if (pf == YCbCrA420p) { pBmps.push_back(getBmp(m_pBmpQ, size, I8)); } } else { pBmps.push_back(getBmp(m_pBmpQ, size, pf)); } frameAvailable = m_pDecoder->renderToBmps(pBmps, -1); } if (m_pDecoder->isEOF(SS_VIDEO)) { VideoMsgPtr pMsg(new VideoMsg()); pMsg->setEOF(); m_MsgQ.push(pMsg); } else { ScopeTimer timer(PushMsgProfilingZone); AVG_ASSERT(frameAvailable == FA_NEW_FRAME); VideoMsgPtr pMsg(new VideoMsg()); if (usesVDPAU) { pMsg->setVDPAUFrame(pRenderState, m_pDecoder->getCurTime(SS_VIDEO)); } else { pMsg->setFrame(pBmps, m_pDecoder->getCurTime(SS_VIDEO)); } m_MsgQ.push(pMsg); msleep(0); } ThreadProfiler::get()->reset(); } return true; }
void VideoDecoderThread::sendFrame(AVFrame* pFrame) { VideoMsgPtr pMsg(new VideoMsg()); vector<BitmapPtr> pBmps; if (pixelFormatIsPlanar(m_PF)) { ScopeTimer timer(CopyImageProfilingZone); IntPoint halfSize(m_Size.x/2, m_Size.y/2); pBmps.push_back(getBmp(m_pBmpQ, m_Size, I8)); pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8)); pBmps.push_back(getBmp(m_pHalfBmpQ, halfSize, I8)); if (m_PF == YCbCrA420p) { pBmps.push_back(getBmp(m_pBmpQ, m_Size, I8)); } for (unsigned i = 0; i < pBmps.size(); ++i) { m_pFrameDecoder->copyPlaneToBmp(pBmps[i], pFrame->data[i], pFrame->linesize[i]); } } else { pBmps.push_back(getBmp(m_pBmpQ, m_Size, m_PF)); m_pFrameDecoder->convertFrameToBmp(pFrame, pBmps[0]); } pMsg->setFrame(pBmps, m_pFrameDecoder->getCurTime()); pushMsg(pMsg); }