LRESULT Frameserver::SessionFormat(LPARAM lParam, WPARAM stream) { FrameserverSession *fs = SessionLookup(lParam); DubSource *ds; long len; if (!fs) return VDSRVERR_BADSESSION; if (stream<0 || stream>2) return VDSRVERR_NOSTREAM; ds = stream ? (DubSource *)aSrc : (DubSource *)vSrc; if (!ds) return VDSRVERR_NOSTREAM; if (stream) { len = aSrc->getFormatLen(); if (len > fs->arena_size) return VDSRVERR_TOOBIG; memcpy(fs->arena, aSrc->getFormat(), len); } else { BITMAPINFOHEADER *bmih; len = sizeof(BITMAPINFOHEADER); if (len > fs->arena_size) return VDSRVERR_TOOBIG; memcpy(fs->arena, vSrc->getDecompressedFormat(), len); bmih = (BITMAPINFOHEADER *)fs->arena; // bmih->biSize = sizeof(BITMAPINFOHEADER); bmih->biWidth = filters.LastBitmap()->w; bmih->biHeight = filters.LastBitmap()->h; bmih->biPlanes = 1; bmih->biCompression = BI_RGB; bmih->biBitCount = 24; bmih->biSizeImage = ((bmih->biWidth*3+3)&-4)*abs(bmih->biHeight); bmih->biClrUsed = 0; bmih->biClrImportant= 0; } return len; }
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; }
void Frameserver::Go(IVDubServerLink *ivdsl, char *name) { int server_index = -1; lpszFsname = name; // prepare the sources... if (vSrc) { if (!vSrc->setTargetFormat(g_dubOpts.video.mInputFormat)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_XRGB8888)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_RGB888)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_XRGB1555)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_Pal8)) throw MyError("The decompression codec cannot decompress to an RGB format. This is very unusual. Check that any \"Force YUY2\" options are not enabled in the codec's properties."); vSrc->streamBegin(true, false); BITMAPINFOHEADER *bmih = vSrc->getDecompressedFormat(); filters.initLinearChain(&g_listFA, (Pixel *)(bmih+1), bmih->biWidth, abs(bmih->biHeight), 24); if (filters.getFrameLag()) MessageBox(g_hWnd, "One or more filters in the filter chain has a non-zero lag. This will cause the served " "video to lag behind the audio!" , "VirtualDub warning", MB_OK); fsi.lMicrosecsPerFrame = vInfo.usPerFrame; fsi.lMicrosecsPerSrcFrame = vInfo.usPerFrameIn; fsi.flags = 0; if (filters.ReadyFilters(fsi)) throw MyError("Error readying filters."); const VBitmap *pvb = filters.LastBitmap(); VDPixmapCreateLinearLayout(mFrameLayout, nsVDPixmap::kPixFormat_RGB888, pvb->w, pvb->h, 4); VDPixmapLayoutFlipV(mFrameLayout); } if (aSrc) aSrc->streamBegin(true, false); // usurp the window VDUIFrame *pFrame = VDUIFrame::GetFrame(hwnd); mpUIFrame = pFrame; pFrame->Attach(this); guiSetTitle(hwnd, IDS_TITLE_FRAMESERVER); // create dialog box mbExit = false; if (hwndStatus = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_SERVER), hwnd, Frameserver::StatusDlgProc, (LPARAM)this)) { // hide the main window ShowWindow(hwnd, SW_HIDE); // create the frameserver server_index = ivdsl->CreateFrameServer(name, hwnd); if (server_index>=0) { // kick us into high priority SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); // enter window loop { MSG msg; while(!mbExit) { BOOL result = GetMessage(&msg, NULL, 0, 0); if (result == (BOOL)-1) break; if (!result) { PostQuitMessage(msg.wParam); break; } TranslateMessage(&msg); DispatchMessage(&msg); } } // return to normal priority SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); ivdsl->DestroyFrameServer(server_index); } if (IsWindow(hwndStatus)) DestroyWindow(hwndStatus); // show the main window ShowWindow(hwnd, SW_SHOW); } // unsubclass pFrame->Detach(); if (vSrc) { vSrc->streamEnd(); } if (server_index<0) throw MyError("Couldn't create frameserver"); }