AviReportWnd.cpp

00001 #include "StdAfx.h"
00002 #include "AviReportWnd.h"
00003 
00004 #define IDC_DONOTSHOWAGAINCHECK 1000
00005 #define TITLE _T("AVI Chunk Viewer")
00006 #define GRAPHFOOTER 10
00007 
00008 CAviReportWnd::CAviReportWnd()
00009 {
00010         m_font.CreateFont(12, 0, 0, 0, 400, 0, 0, 0, 1, 0, 0, 0, 0, _T("MS Shell Dlg"));
00011 }
00012 
00013 bool CAviReportWnd::DoModal(CAviFile* pAF, bool fHideChecked, bool fShowWarningText)
00014 {
00015         m_nChunks = 0;
00016         m_rtDur = 0;
00017 
00018         for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
00019         {
00020                 int cnt = pAF->m_strms[i]->cs2.GetCount();
00021                 if(cnt <= 0) continue;
00022                 CAviFile::strm_t::chunk2& c2 = pAF->m_strms[i]->cs2[cnt-1];
00023                 m_nChunks = max(m_nChunks, c2.n);
00024                 m_rtDur = max(m_rtDur, (REFERENCE_TIME)c2.t<<13);
00025         }
00026 
00027         CRect r, r2;
00028         GetDesktopWindow()->GetWindowRect(r);
00029         r.DeflateRect(r.Width()/4, r.Height()/4);
00030 
00031         LPCTSTR wndclass = AfxRegisterWndClass(
00032                 CS_VREDRAW|CS_HREDRAW|CS_DBLCLKS, 
00033                 AfxGetApp()->LoadStandardCursor(IDC_ARROW), 
00034                 (HBRUSH)(COLOR_BTNFACE + 1), 0);
00035 
00036         CreateEx(0, wndclass, TITLE, WS_POPUPWINDOW|WS_CAPTION|WS_CLIPCHILDREN, r, NULL, 0);
00037 
00038         CRect cr;
00039         GetClientRect(cr);
00040         cr.DeflateRect(10, 10);
00041 
00042         SetFont(&m_font, FALSE);
00043 
00044         CDC* pDC = GetDC();
00045         CFont* pOldFont = pDC->SelectObject(&m_font);
00046 
00047         //
00048 
00049         CString str(
00050                 _T("This AVI file was not prepared for sequential reading, the alternative ")
00051                 _T("'Avi Splitter' will now let the default one handle it. ")
00052                 _T("The complete reinterleaving of this file is strongly recommended before ")
00053                 _T("burning it onto a slow media like cd-rom."));
00054 
00055         r = cr;
00056 
00057         pDC->DrawText(str, r, DT_WORDBREAK|DT_CALCRECT);
00058         r.right = cr.right;
00059 
00060         m_message.Create(str, WS_CHILD|WS_VISIBLE, r, this);
00061         m_message.SetFont(&m_font, FALSE);
00062 
00063         //
00064 
00065         r.SetRect(cr.left, r.bottom + 10, cr.right, cr.bottom);
00066 
00067         str = _T("Do not show this dialog again (hold Shift to re-enable it)");
00068 
00069         pDC->DrawText(str, r, DT_WORDBREAK|DT_CALCRECT);
00070         r.right = cr.right;
00071 
00072         m_checkbox.Create(str, WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, r, this, IDC_DONOTSHOWAGAINCHECK);
00073         m_checkbox.SetFont(&m_font, FALSE);
00074 
00075         CheckDlgButton(IDC_DONOTSHOWAGAINCHECK, fHideChecked?BST_CHECKED:BST_UNCHECKED);
00076 
00077         //
00078 
00079         if(!fShowWarningText)
00080         {
00081                 m_message.ShowWindow(SW_HIDE);
00082                 m_checkbox.ShowWindow(SW_HIDE);
00083                 r = cr;
00084         }
00085         else
00086         {
00087                 r.SetRect(cr.left, r.bottom + 10, cr.right, cr.bottom);
00088         }
00089 
00090         m_graph.Create(pAF, r, this);
00091 
00092         //
00093 
00094         pDC->SelectObject(pOldFont);
00095         ReleaseDC(pDC);
00096 
00097         SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
00098         SetForegroundWindow();
00099         ShowWindow(SW_SHOWNORMAL);
00100 
00101         return !!RunModalLoop();
00102 }
00103 
00104 IMPLEMENT_DYNCREATE(CAviReportWnd, CWnd)
00105 
00106 BEGIN_MESSAGE_MAP(CAviReportWnd, CWnd)
00107         ON_WM_CLOSE()
00108         ON_WM_MOUSEMOVE()
00109 END_MESSAGE_MAP()
00110 
00111 void CAviReportWnd::OnClose()
00112 {
00113         EndModalLoop(IsDlgButtonChecked(IDC_DONOTSHOWAGAINCHECK));
00114         __super::OnClose();
00115 }
00116 
00117 void CAviReportWnd::OnMouseMove(UINT nFlags, CPoint p)
00118 {
00119         MapWindowPoints(&m_graph, &p, 1);
00120 
00121         CRect r, r2;
00122         m_graph.GetClientRect(r);
00123         r2 = r;
00124         r.bottom -= GRAPHFOOTER;
00125         r2.top = r.bottom;
00126 
00127         if(r.PtInRect(p))
00128         {
00129                 SetCapture();
00130 
00131                 int x = p.x - r.left;
00132                 int y = r.bottom - p.y;
00133 
00134                 REFERENCE_TIME rt = m_rtDur * x / r.Width();
00135                 int chunk = (int)(1.0 * m_nChunks * y / r.Height());
00136 
00137                 rt /= 10000;
00138                 int ms = (int)(rt%1000);
00139                 rt /= 1000;
00140                 int s = (int)(rt%60);
00141                 rt /= 60;
00142                 int m = (int)(rt%60);
00143                 rt /= 60;
00144                 int h = (int)(rt);
00145 
00146                 CString str;
00147                 str.Format(_T("%s (%d - %d:%02d:%02d.%03d)"), TITLE, chunk, h, m, s, ms);
00148                 SetWindowText(str);
00149         }
00150         else if(r2.PtInRect(p))
00151         {
00152                 SetCapture();
00153 
00154                 int dist = m_graph.GetChunkDist(p.x - r2.left);
00155                 CString str;
00156                 str.Format(_T("%s (chunk distance: %d"), TITLE, dist);
00157                 if(dist >= 1000) str += _T(" - over the limit!");
00158                 str += ")";
00159                 SetWindowText(str);
00160         }
00161         else if(GetCapture() == this)
00162         {
00163                 SetWindowText(TITLE);
00164 
00165                 ReleaseCapture();
00166         }
00167 
00168         __super::OnMouseMove(nFlags, p);
00169 }
00170 
00172 
00173 CAviPlotterWnd::CAviPlotterWnd()
00174 {
00175 }
00176 
00177 bool CAviPlotterWnd::Create(CAviFile* pAF, CRect r, CWnd* pParentWnd)
00178 {
00179         if(!CreateEx(WS_EX_CLIENTEDGE, _T("STATIC"), _T(""), WS_CHILD|WS_VISIBLE, r, pParentWnd, 0))
00180                 return(false);
00181 
00182         GetClientRect(r);
00183         int w = r.Width();
00184         int h = r.Height() - GRAPHFOOTER;
00185 
00186         CDC* pDC = GetDC();
00187         m_dc.CreateCompatibleDC(pDC);
00188         m_bm.CreateCompatibleBitmap(pDC, r.Width(), r.Height());
00189         ReleaseDC(pDC);
00190 
00191         CBitmap* pOldBitmap = m_dc.SelectObject(&m_bm);
00192         
00193         m_dc.FillSolidRect(r, 0);
00194 
00195         {
00196                 CPen pen(PS_DOT, 1, 0x008000);
00197                 CPen* pOldPen = m_dc.SelectObject(&pen);
00198                 for(int y = 0, dy = max(h/10,1); y < h; y += dy) {if(y == 0) continue; m_dc.MoveTo(0, y); m_dc.LineTo(w, y);}
00199                 for(int x = 0, dx = max(w/10,1); x < w; x += dx) {if(x == 0) continue; m_dc.MoveTo(x, 0); m_dc.LineTo(x, w);}
00200                 m_dc.SelectObject(pOldPen);
00201         }
00202 
00203         {
00204                 CPen pen(PS_SOLID, 1, 0x00ff00);
00205                 CPen* pOldPen = m_dc.SelectObject(&pen);
00206                 m_dc.MoveTo(15, 30);
00207                 m_dc.LineTo(15, 2);
00208                 m_dc.LineTo(19, 10);
00209                 m_dc.LineTo(11, 10);
00210                 m_dc.LineTo(15, 2);
00211                 m_dc.MoveTo(w-30-10, h-15); 
00212                 m_dc.LineTo(w-2-10, h-15);
00213                 m_dc.LineTo(w-10-10, h-19);
00214                 m_dc.LineTo(w-10-10, h-11);
00215                 m_dc.LineTo(w-2-10, h-15);
00216                 m_dc.SelectObject(pOldPen);
00217 
00218                 m_dc.SetTextColor(0x008000);
00219                 m_dc.TextOut(20, 10, _T("Chunk"));
00220 
00221                 CSize size = m_dc.GetTextExtent(_T("Time"));
00222                 m_dc.TextOut(w - size.cx - 10, h - size.cy - 20, _T("Time"));
00223         }
00224 
00225         COLORREF clr[] = {0x0000ff,0xff0000,0x40ffff,0xff40ff,0xffff40,0xffffff};
00226 
00227         for(int i = 0, y = 40, dy = m_dc.GetTextExtent(_T("Stream N")).cy + 1; i < (int)pAF->m_avih.dwStreams; i++, y += dy)
00228         {
00229                 m_dc.SetTextColor(clr[i%pAF->m_avih.dwStreams]);
00230                 m_dc.SetBkMode(TRANSPARENT);
00231                 CString str;
00232                 str.Format(_T("Stream %d"), i);
00233                 m_dc.TextOut(10, y, str);
00234         }
00235 
00236         DWORD nmax = 0, tmax = 0;
00237 
00238         for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
00239         {
00240                 int cnt = pAF->m_strms[i]->cs2.GetCount();
00241                 if(cnt <= 0) continue;
00242                 CAviFile::strm_t::chunk2& c2 = pAF->m_strms[i]->cs2[cnt-1];
00243                 nmax = max(nmax, c2.n);
00244                 tmax = max(tmax, c2.t);
00245         }
00246 
00247         if(nmax > 0 && tmax > 0)
00248         {
00249                 CArray<CPen> pen;
00250                 pen.SetSize(pAF->m_avih.dwStreams);
00251                 for(int i = 0; i < pen.GetSize(); i++)
00252                         pen[i].CreatePen(PS_SOLID, 2, clr[i]);
00253 
00254                 CArray<CPoint> pp;
00255                 pp.SetSize(pAF->m_avih.dwStreams);
00256                 for(int i = 0; i < pen.GetSize(); i++)
00257                         pp[i].SetPoint(-1, -1);
00258 
00259                 m_chunkdist.SetSize(w);
00260                 memset(m_chunkdist.GetData(), 0, sizeof(int)*w);
00261 
00262                 DWORD* curchunks = new DWORD[pAF->m_avih.dwStreams];
00263                 memset(curchunks, 0, sizeof(DWORD)*pAF->m_avih.dwStreams);
00264 
00265                 CAviFile::strm_t::chunk2 cs2last = {-1, 0};
00266 
00267                 while(1)
00268                 {
00269                         CAviFile::strm_t::chunk2 cs2min = {LONG_MAX, LONG_MAX};
00270 
00271                         int n = -1;
00272                         for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
00273                         {
00274                                 int curchunk = curchunks[i];
00275                                 if(curchunk >= pAF->m_strms[i]->cs2.GetSize()) continue;
00276                                 CAviFile::strm_t::chunk2& cs2 = pAF->m_strms[i]->cs2[curchunk];
00277                                 if(cs2.t < cs2min.t) {cs2min = cs2; n = i;}
00278                         }
00279                         if(n == -1) break;
00280 
00281 
00282                         CPoint p;
00283                         p.x = (int)(1.0 * w * cs2min.t / tmax);
00284                         p.y = (int)(h - 1.0 * h * cs2min.n / nmax);
00285                         if(pp[n] != p)
00286                         {
00287                                 CPen* pOldPen = m_dc.SelectObject(&pen[n]);
00288                                 if(pp[n] == CPoint(-1, -1)) m_dc.MoveTo(p);
00289                                 else {m_dc.MoveTo(pp[n]); m_dc.LineTo(p);}
00290                                 m_dc.SelectObject(pOldPen);
00291                                 pp[n] = p;
00292                         }
00293 
00294                         int dist = abs(cs2min.n - cs2last.n);
00295 
00296                         if(cs2last.t >= 0 /*&& dist >= 1000*/)
00297                         {
00298                                 if(p.x >= 0 && p.x < w)
00299                                 {
00300                                         m_chunkdist[p.x] = max(m_chunkdist[p.x], dist);
00301                                 }
00302                         }
00303 
00304                         curchunks[n]++;
00305                         cs2last = cs2min;
00306                 }
00307 
00308                 CPen red(PS_SOLID, 1, 0x0000ff);
00309                 CPen green(PS_SOLID, 1, 0x00ff00);
00310 
00311                 for(int x = 0; x < w; x++)
00312                 {
00313                         CPen* pOldPen = m_dc.SelectObject(m_chunkdist[x] >= 1000 ? &red : &green);
00314                         m_dc.MoveTo(x, h);
00315                         m_dc.LineTo(x, h + GRAPHFOOTER);
00316                         m_dc.SelectObject(pOldPen);
00317                 }
00318 
00319                 delete [] curchunks;
00320         }
00321 
00322         m_dc.SelectObject(pOldBitmap);
00323 
00324         return(true);
00325 }
00326 
00327 IMPLEMENT_DYNCREATE(CAviPlotterWnd, CWnd)
00328 
00329 BEGIN_MESSAGE_MAP(CAviPlotterWnd, CWnd)
00330         ON_WM_PAINT()
00331 END_MESSAGE_MAP()
00332 
00333 void CAviPlotterWnd::OnPaint()
00334 {
00335         CPaintDC dc(this); // device context for painting
00336 
00337         CRect r;
00338         GetClientRect(r);
00339 
00340         CBitmap* pOld = m_dc.SelectObject(&m_bm);
00341         dc.BitBlt(0, 0, r.Width(), r.Height(), &m_dc, 0, 0, SRCCOPY);
00342         m_dc.SelectObject(pOld);
00343 }
00344 

Generated on Tue Dec 13 14:47:10 2005 for guliverkli by  doxygen 1.4.5