Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - void CMainFrame::SaveThumbnails(LPCTSTR fn)
- {
- if (!pMC || !pMS || GetPlaybackMode() != PM_FILE /*&& GetPlaybackMode() != PM_DVD*/) {
- return;
- }
- REFERENCE_TIME rtPos = GetPos();
- REFERENCE_TIME rtDur = GetDur();
- if (rtDur <= 0) {
- AfxMessageBox(IDS_MAINFRM_54, MB_ICONWARNING | MB_OK, 0);
- return;
- }
- pMC->Pause();
- GetMediaState(); // wait for completion of the pause command
- CSize video, wh(0, 0), arxy(0, 0);
- if (m_pMFVDC) {
- m_pMFVDC->GetNativeVideoSize(&wh, &arxy);
- } else if (m_pCAP) {
- wh = m_pCAP->GetVideoSize(false);
- arxy = m_pCAP->GetVideoSize(true);
- } else {
- pBV->GetVideoSize(&wh.cx, &wh.cy);
- long arx = 0, ary = 0;
- CComQIPtr<IBasicVideo2> pBV2 = pBV;
- if (pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0) {
- arxy.SetSize(arx, ary);
- }
- }
- if (wh.cx <= 0 || wh.cy <= 0) {
- AfxMessageBox(IDS_MAINFRM_55, MB_ICONWARNING | MB_OK, 0);
- return;
- }
- // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
- DVD_VideoAttributes VATR;
- if (GetPlaybackMode() == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR))) {
- arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
- }
- video = (arxy.cx <= 0 || arxy.cy <= 0) ? wh : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
- //
- const CAppSettings& s = AfxGetAppSettings();
- int cols = max(1, min(10, s.iThumbCols)), rows = max(1, min(20, s.iThumbRows));
- int margin = 5;
- int infoheight = 70;
- int width = max(256, min(2560, s.iThumbWidth));
- int height = width * video.cy / video.cx * rows / cols + infoheight;
- int dibsize = sizeof(BITMAPINFOHEADER) + width * height * 4;
- CAutoVectorPtr<BYTE> dib;
- if (!dib.Allocate(dibsize)) {
- AfxMessageBox(IDS_MAINFRM_56, MB_ICONWARNING | MB_OK, 0);
- return;
- }
- BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(BYTE*)dib;
- memset(bih, 0, sizeof(BITMAPINFOHEADER));
- bih->biSize = sizeof(BITMAPINFOHEADER);
- bih->biWidth = width;
- bih->biHeight = height;
- bih->biPlanes = 1;
- bih->biBitCount = 32;
- bih->biCompression = BI_RGB;
- bih->biSizeImage = width * height * 4;
- memsetd(bih + 1, 0xffffff, bih->biSizeImage);
- SubPicDesc spd;
- spd.w = width;
- spd.h = height;
- spd.bpp = 32;
- spd.pitch = -width * 4;
- spd.vidrect = CRect(0, 0, width, height);
- spd.bits = (BYTE*)(bih + 1) + (width * 4) * (height - 1);
- {
- BYTE* p = (BYTE*)spd.bits;
- for (int y = 0; y < spd.h; y++, p += spd.pitch)
- for (int x = 0; x < spd.w; x++) {
- ((DWORD*)p)[x] = 0x010101 * (0xe0 + 0x08 * y / spd.h + 0x18 * (spd.w - x) / spd.w);
- }
- }
- CCritSec csSubLock;
- RECT bbox;
- for (int i = 1, pics = cols * rows; i <= pics; i++) {
- REFERENCE_TIME rt = rtDur * i / (pics + 1);
- DVD_HMSF_TIMECODE hmsf = RT2HMS_r(rt);
- SeekTo(rt);
- m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
- pBA->put_Volume(-10000);
- HRESULT hr = pFS ? pFS->Step(1, NULL) : E_FAIL;
- if (FAILED(hr)) {
- pBA->put_Volume(m_VolumeBeforeFrameStepping);
- AfxMessageBox(IDS_FRAME_STEP_ERROR_RENDERER, MB_ICONEXCLAMATION | MB_OK, 0);
- return;
- }
- HANDLE hGraphEvent = NULL;
- pME->GetEventHandle((OAEVENT*)&hGraphEvent);
- while (hGraphEvent && WaitForSingleObject(hGraphEvent, INFINITE) == WAIT_OBJECT_0) {
- LONG evCode = 0;
- LONG_PTR evParam1, evParam2;
- while (pME && SUCCEEDED(pME->GetEvent(&evCode, &evParam1, &evParam2, 0))) {
- pME->FreeEventParams(evCode, evParam1, evParam2);
- if (EC_STEP_COMPLETE == evCode) {
- hGraphEvent = NULL;
- }
- }
- }
- pBA->put_Volume(m_VolumeBeforeFrameStepping);
- int col = (i - 1) % cols;
- int row = (i - 1) / cols;
- CSize siz((width - margin * 2) / cols, (height - margin * 2 - infoheight) / rows);
- CPoint p(margin + col * siz.cx, margin + row * siz.cy + infoheight);
- CRect r(p, siz);
- r.DeflateRect(margin, margin);
- CRenderedTextSubtitle rts(&csSubLock);
- rts.CreateDefaultStyle(0);
- rts.m_dstScreenSize.SetSize(width, height);
- STSStyle* style = DNew STSStyle();
- style->marginRect.SetRectEmpty();
- rts.AddStyle(_T("thumbs"), style);
- CStringW str;
- str.Format(L"{\\an7\\1c&Hffffff&\\4a&Hb0&\\bord1\\shad4\\be1}{\\p1}m %d %d l %d %d %d %d %d %d{\\p}",
- r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom);
- rts.Add(str, true, 0, 1, _T("thumbs"));
- str.Format(L"{\\an3\\1c&Hffffff&\\3c&H000000&\\alpha&H80&\\fs16\\b1\\bord2\\shad0\\pos(%d,%d)}%02d:%02d:%02d",
- r.right - 5, r.bottom - 3, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
- rts.Add(str, true, 1, 2, _T("thumbs"));
- rts.Render(spd, 0, 25, bbox);
- BYTE* pData = NULL;
- long size = 0;
- if (!GetDIB(&pData, size)) {
- return;
- }
- BITMAPINFO* bi = (BITMAPINFO*)pData;
- if (bi->bmiHeader.biBitCount != 32) {
- delete [] pData;
- CString strTemp;
- strTemp.Format(IDS_MAINFRM_57, bi->bmiHeader.biBitCount);
- AfxMessageBox(strTemp);
- return;
- }
- int sw = bi->bmiHeader.biWidth;
- int sh = abs(bi->bmiHeader.biHeight);
- int sp = sw * 4;
- const BYTE* src = pData + sizeof(bi->bmiHeader);
- if (bi->bmiHeader.biHeight >= 0) {
- src += sp * (sh - 1);
- sp = -sp;
- }
- int dp = spd.pitch;
- BYTE* dst = (BYTE*)spd.bits + spd.pitch * r.top + r.left * 4;
- for (DWORD h = r.bottom - r.top, y = 0, yd = (sh << 8) / h; h > 0; y += yd, h--) {
- DWORD yf = y & 0xff;
- DWORD yi = y >> 8;
- DWORD* s0 = (DWORD*)(src + (int)yi * sp);
- DWORD* s1 = (DWORD*)(src + (int)yi * sp + sp);
- DWORD* d = (DWORD*)dst;
- for (DWORD w = r.right - r.left, x = 0, xd = (sw << 8) / w; w > 0; x += xd, w--) {
- DWORD xf = x & 0xff;
- DWORD xi = x >> 8;
- DWORD c0 = s0[xi];
- DWORD c1 = s0[xi + 1];
- DWORD c2 = s1[xi];
- DWORD c3 = s1[xi + 1];
- c0 = ((c0 & 0xff00ff) + ((((c1 & 0xff00ff) - (c0 & 0xff00ff)) * xf) >> 8)) & 0xff00ff
- | ((c0 & 0x00ff00) + ((((c1 & 0x00ff00) - (c0 & 0x00ff00)) * xf) >> 8)) & 0x00ff00;
- c2 = ((c2 & 0xff00ff) + ((((c3 & 0xff00ff) - (c2 & 0xff00ff)) * xf) >> 8)) & 0xff00ff
- | ((c2 & 0x00ff00) + ((((c3 & 0x00ff00) - (c2 & 0x00ff00)) * xf) >> 8)) & 0x00ff00;
- c0 = ((c0 & 0xff00ff) + ((((c2 & 0xff00ff) - (c0 & 0xff00ff)) * yf) >> 8)) & 0xff00ff
- | ((c0 & 0x00ff00) + ((((c2 & 0x00ff00) - (c0 & 0x00ff00)) * yf) >> 8)) & 0x00ff00;
- *d++ = c0;
- }
- dst += dp;
- }
- rts.Render(spd, 10000, 25, bbox);
- delete [] pData;
- }
- {
- CRenderedTextSubtitle rts(&csSubLock);
- rts.CreateDefaultStyle(0);
- rts.m_dstScreenSize.SetSize(width, height);
- STSStyle* style = DNew STSStyle();
- style->marginRect.SetRect(margin * 2, margin * 2, margin * 2, height - infoheight - margin);
- rts.AddStyle(_T("thumbs"), style);
- CStringW str;
- str.Format(L"{\\an9\\fs%d\\b1\\bord0\\shad0\\1c&Hffffff&}%s", infoheight - 10, width >= 550 ? L"Media Player Classic" : L"MPC");
- rts.Add(str, true, 0, 1, _T("thumbs"), _T(""), _T(""), CRect(0, 0, 0, 0), -1);
- DVD_HMSF_TIMECODE hmsf = RT2HMS_r(rtDur);
- CPath path(m_wndPlaylistBar.GetCurFileName());
- path.StripPath();
- CStringW fnp = (LPCTSTR)path;
- CStringW fs;
- WIN32_FIND_DATA wfd;
- HANDLE hFind = FindFirstFile(m_wndPlaylistBar.GetCurFileName(), &wfd);
- if (hFind != INVALID_HANDLE_VALUE) {
- FindClose(hFind);
- __int64 size = (__int64(wfd.nFileSizeHigh) << 32) | wfd.nFileSizeLow;
- const int MAX_FILE_SIZE_BUFFER = 65;
- WCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
- StrFormatByteSizeW(size, szFileSize, MAX_FILE_SIZE_BUFFER);
- CString szByteSize;
- szByteSize.Format(_T("%I64d"), size);
- fs.Format(IDS_MAINFRM_58, szFileSize, FormatNumber(szByteSize));
- }
- CStringW ar;
- if (arxy.cx > 0 && arxy.cy > 0 && arxy.cx != wh.cx && arxy.cy != wh.cy) {
- ar.Format(L"(%d:%d)", arxy.cx, arxy.cy);
- }
- str.Format(IDS_MAINFRM_59,
- fnp, fs, wh.cx, wh.cy, ar, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
- rts.Add(str, true, 0, 1, _T("thumbs"));
- rts.Render(spd, 0, 25, bbox);
- }
- SaveDIB(fn, (BYTE*)dib, dibsize);
- SeekTo(rtPos);
- m_OSD.DisplayMessage(OSD_TOPLEFT, ResStr(IDS_OSD_THUMBS_SAVED), 3000);
- }
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment                    
                 
                    