void VDVideoDecompressorHuffyuv::DecompressFrame(void *dst, const void *src, uint32 srcSize, bool keyframe, bool preroll) { if (!mFormat) throw MyError("Cannot find compatible target format for video decompression."); mpDecoder->DecompressFrame(src, srcSize); // blit time! VDPixmap pxsrc(mpDecoder->GetFrameBuffer()); VDPixmapLayout dstlayout; VDMakeBitmapCompatiblePixmapLayout(dstlayout, mWidth, mHeight, mFormat, 0); VDPixmap pxdst(VDPixmapFromLayout(dstlayout, dst)); VDPixmapBlt(pxdst, pxsrc); }
LRESULT Frameserver::SessionFrame(LPARAM lParam, WPARAM original_frame) { FrameserverSession *fs = SessionLookup(lParam); if (!fs) return VDSRVERR_BADSESSION; try { const VDPixmapLayout& output = filters.GetOutputLayout(); if (fs->arena_size < ((output.w*3+3)&-4)*output.h) return VDSRVERR_TOOBIG; VDPosition pos = mVideoFrameMap[original_frame].mSourceFrame; if (pos < 0) return VDSRVERR_FAILED; vdrefptr<IVDFilterFrameClientRequest> creq; filters.RequestFrame(pos, 0, ~creq); while(!creq->IsCompleted()) { if (filters.Run(NULL, false) == FilterSystem::kRunResult_Running) continue; switch(mpVideoFrameSource->RunRequests(NULL)) { case IVDFilterFrameSource::kRunResult_Running: case IVDFilterFrameSource::kRunResult_IdleWasActive: case IVDFilterFrameSource::kRunResult_BlockedWasActive: continue; } filters.Block(); } VDPixmap pxdst(VDPixmapFromLayout(mFrameLayout, fs->arena)); VDFilterFrameBuffer *buf = creq->GetResultBuffer(); VDPixmapBlt(pxdst, VDPixmapFromLayout(filters.GetOutputLayout(), (void *)buf->LockRead())); buf->Unlock(); } catch(const MyError&) { return VDSRVERR_FAILED; } return VDSRVERR_OK; }
LRESULT Frameserver::SessionFrame(LPARAM lParam, WPARAM original_frame) { FrameserverSession *fs = SessionLookup(lParam); if (!fs) return VDSRVERR_BADSESSION; try { const void *ptr = vSrc->getFrameBuffer(); const BITMAPINFOHEADER *bmih = vSrc->getDecompressedFormat(); VDPosition sample; bool is_preroll; if (fs->arena_size < ((filters.LastBitmap()->w*3+3)&-4)*filters.LastBitmap()->h) return VDSRVERR_TOOBIG; sample = mVideoFrameMap[original_frame].mDisplayFrame; if (sample < 0) return VDSRVERR_FAILED; vSrc->streamSetDesiredFrame(sample); VDPosition targetSample = vSrc->displayToStreamOrder(sample); VDPosition frame = vSrc->streamGetNextRequiredFrame(is_preroll); if (frame >= 0) { do { uint32 lSize; int hr; // _RPT1(0,"feeding frame %ld\n", frame); hr = vSrc->read(frame, 1, NULL, 0x7FFFFFFF, &lSize, NULL); if (hr) return VDSRVERR_FAILED; uint32 bufSize = (lSize + 65535 + vSrc->streamGetDecodePadding()) & ~65535; if (mInputBuffer.size() < bufSize) mInputBuffer.resize(bufSize); hr = vSrc->read(frame, 1, mInputBuffer.data(), lSize, &lSize, NULL); if (hr) return VDSRVERR_FAILED; vSrc->streamFillDecodePadding(mInputBuffer.data(), lSize); ptr = vSrc->streamGetFrame(mInputBuffer.data(), lSize, is_preroll, frame, targetSample); } while(-1 != (frame = vSrc->streamGetNextRequiredFrame(is_preroll))); } else ptr = vSrc->streamGetFrame(NULL, 0, FALSE, targetSample, targetSample); VDPixmap pxdst(VDPixmapFromLayout(mFrameLayout, fs->arena)); if (!g_listFA.IsEmpty()) { VDPixmapBlt(VDAsPixmap(*filters.InputBitmap()), vSrc->getTargetFormat()); fsi.lCurrentFrame = original_frame; fsi.lCurrentSourceFrame = sample; fsi.lSourceFrameMS = MulDiv(fsi.lCurrentSourceFrame, fsi.lMicrosecsPerSrcFrame, 1000); fsi.lDestFrameMS = MulDiv(fsi.lCurrentFrame, fsi.lMicrosecsPerFrame, 1000); filters.RunFilters(fsi); VDPixmapBlt(pxdst, VDAsPixmap(*filters.LastBitmap())); } else VDPixmapBlt(pxdst, vSrc->getTargetFormat()); } catch(const MyError&) { return VDSRVERR_FAILED; } return VDSRVERR_OK; }