- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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