summaryrefslogtreecommitdiffstats
path: root/media/tools/player_wtl
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 18:43:53 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 18:43:53 +0000
commit6e7c24ee5cd7ce88266ceae158c31c62d7498d3f (patch)
tree7fe0d691192959f1a31095aa35dc5efb147f88c8 /media/tools/player_wtl
parenta999b0e58e1ca80435c7322df5cb229b64be113f (diff)
downloadchromium_src-6e7c24ee5cd7ce88266ceae158c31c62d7498d3f.zip
chromium_src-6e7c24ee5cd7ce88266ceae158c31c62d7498d3f.tar.gz
chromium_src-6e7c24ee5cd7ce88266ceae158c31c62d7498d3f.tar.bz2
Re-organizing all tools under /src/media to be consistent with the rest of the repository.
TEST=n/a BUG=n/a Review URL: http://codereview.chromium.org/431046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33089 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/tools/player_wtl')
-rw-r--r--media/tools/player_wtl/list.h127
-rw-r--r--media/tools/player_wtl/mainfrm.h718
-rw-r--r--media/tools/player_wtl/movie.cc172
-rw-r--r--media/tools/player_wtl/movie.h98
-rw-r--r--media/tools/player_wtl/player_wtl.cc93
-rw-r--r--media/tools/player_wtl/player_wtl.h28
-rw-r--r--media/tools/player_wtl/player_wtl.icobin0 -> 1078 bytes
-rw-r--r--media/tools/player_wtl/player_wtl.rc544
-rw-r--r--media/tools/player_wtl/props.h325
-rw-r--r--media/tools/player_wtl/resource.h78
-rw-r--r--media/tools/player_wtl/seek.h97
-rw-r--r--media/tools/player_wtl/toolbar.bmpbin0 -> 1438 bytes
-rw-r--r--media/tools/player_wtl/view.h420
-rw-r--r--media/tools/player_wtl/wtl_renderer.cc38
-rw-r--r--media/tools/player_wtl/wtl_renderer.h36
15 files changed, 2774 insertions, 0 deletions
diff --git a/media/tools/player_wtl/list.h b/media/tools/player_wtl/list.h
new file mode 100644
index 0000000..f3b8d5b
--- /dev/null
+++ b/media/tools/player_wtl/list.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_LIST_H_
+#define MEDIA_TOOLS_PLAYER_WTL_LIST_H_
+
+#include "media/tools/player_wtl/player_wtl.h"
+
+// Recent Files list.
+class CMruList : public CWindowImpl<CMruList, CListBox> {
+ public:
+
+ CMruList() {
+ size_.cx = 400;
+ size_.cy = 150;
+ }
+
+ HWND Create(HWND parent) {
+ CWindowImpl<CMruList, CListBox>::Create(parent, rcDefault, NULL,
+ WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
+ WS_VSCROLL | LBS_NOINTEGRALHEIGHT,
+ WS_EX_CLIENTEDGE);
+ if (IsWindow())
+ SetFont(AtlGetStockFont(DEFAULT_GUI_FONT));
+ return m_hWnd;
+ }
+
+ BOOL BuildList(CRecentDocumentList& mru) {
+ ATLASSERT(IsWindow());
+
+ ResetContent();
+
+ int docs_size = mru.m_arrDocs.GetSize();
+ for (int i = 0; i < docs_size; i++)
+ InsertString(0, mru.m_arrDocs[i].szDocName); // Reverse order in array.
+
+ if (docs_size > 0) {
+ SetCurSel(0);
+ SetTopIndex(0);
+ }
+
+ return TRUE;
+ }
+
+ BOOL ShowList(int x, int y) {
+ return SetWindowPos(NULL, x, y, size_.cx, size_.cy,
+ SWP_NOZORDER | SWP_SHOWWINDOW);
+ }
+
+ void HideList() {
+ RECT rect;
+ GetWindowRect(&rect);
+ size_.cx = rect.right - rect.left;
+ size_.cy = rect.bottom - rect.top;
+ ShowWindow(SW_HIDE);
+ }
+
+ void FireCommand() {
+ int selection = GetCurSel();
+ if (selection != LB_ERR) {
+ ::SetFocus(GetParent()); // Will hide this window.
+ ::SendMessage(GetParent(), WM_COMMAND,
+ MAKEWPARAM((WORD)(ID_FILE_MRU_FIRST + selection),
+ LBN_DBLCLK), (LPARAM)m_hWnd);
+ }
+ }
+
+ BEGIN_MSG_MAP(CMruList)
+ MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
+ MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
+ MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
+ MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
+ END_MSG_MAP()
+
+ LRESULT OnKeyDown(UINT /*message*/,
+ WPARAM wparam,
+ LPARAM /*lparam*/,
+ BOOL& handled) {
+ if (wparam == VK_RETURN)
+ FireCommand();
+ else
+ handled = FALSE;
+ return 0;
+ }
+
+ LRESULT OnLButtonDblClk(UINT /*message*/,
+ WPARAM /*wparam*/,
+ LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ FireCommand();
+ return 0;
+ }
+
+ LRESULT OnKillFocus(UINT /*message*/,
+ WPARAM /*wparam*/,
+ LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ HideList();
+ return 0;
+ }
+
+ LRESULT OnNcHitTest(UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ BOOL& /*handled*/) {
+ LRESULT result = DefWindowProc(message, wparam, lparam);
+ switch (result) {
+ case HTLEFT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT:
+ case HTBOTTOMLEFT:
+ result = HTCLIENT; // Don't allow resizing here.
+ break;
+ default:
+ break;
+ }
+ return result;
+ }
+
+ private:
+
+ SIZE size_;
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_LIST_H_
diff --git a/media/tools/player_wtl/mainfrm.h b/media/tools/player_wtl/mainfrm.h
new file mode 100644
index 0000000..7379f71
--- /dev/null
+++ b/media/tools/player_wtl/mainfrm.h
@@ -0,0 +1,718 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_MAINFRM_H_
+#define MEDIA_TOOLS_PLAYER_WTL_MAINFRM_H_
+
+#include "media/tools/player_wtl/list.h"
+#include "media/tools/player_wtl/props.h"
+#include "media/tools/player_wtl/seek.h"
+#include "media/tools/player_wtl/view.h"
+
+const int POPUP_MENU_POSITION = 0;
+const int FILE_MENU_POSITION = 0;
+const int RECENT_MENU_POSITION = 6;
+
+const wchar_t* const g_lpcstrMRURegKey =
+ L"Software\\Google\\Video\\MediaPlayer";
+const wchar_t* const g_lpcstrApp = L"MediaPlayer";
+
+// Interface of the CMainFrame class
+// TODO(fbarchard): Remove hungarian notation.
+class CMainFrame : public CFrameWindowImpl<CMainFrame>,
+ public CUpdateUI<CMainFrame>,
+ public CMessageFilter, public CIdleHandler,
+ public CPrintJobInfo {
+ public:
+ DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
+
+ CCommandBarCtrl m_CmdBar;
+ CRecentDocumentList m_mru;
+ CMruList m_list;
+ WtlVideoWindow m_view;
+
+ wchar_t m_szFilePath[MAX_PATH];
+ bool enable_exit;
+
+ // printing support
+ CPrinter m_printer;
+ CDevMode m_devmode;
+ CPrintPreviewWindow m_wndPreview;
+ CEnhMetaFile m_enhmetafile;
+ RECT m_rcMargin;
+ bool m_bPrintPreview;
+
+ CMainFrame()
+ : m_bPrintPreview(false) {
+ ::SetRect(&m_rcMargin, 1000, 1000, 1000, 1000);
+ m_printer.OpenDefaultPrinter();
+ m_devmode.CopyFromPrinter(m_printer);
+ m_szFilePath[0] = 0;
+ enable_exit = false;
+ }
+
+ virtual BOOL PreTranslateMessage(MSG* pMsg) {
+ if (CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
+ return TRUE;
+
+ return m_view.PreTranslateMessage(pMsg);
+ }
+
+ virtual BOOL OnIdle() {
+ BOOL bEnable = !m_view.bmp_.IsNull();
+ BOOL bMovieOpen = media::Movie::get()->IsOpen() ? true : false;
+
+ float current_position = media::Movie::get()->GetPosition();
+ float duration = media::Movie::get()->GetDuration();
+ if (enable_exit && bEnable &&
+ duration > 0.0f && current_position >= duration) {
+ OnFileExit(0, 0, 0);
+ }
+
+ UIEnable(ID_FILE_PRINT, bEnable);
+ UIEnable(ID_FILE_PRINT_PREVIEW, bEnable);
+ UISetCheck(ID_FILE_PRINT_PREVIEW, m_bPrintPreview);
+ UIEnable(ID_EDIT_COPY, bEnable);
+ UIEnable(ID_EDIT_PASTE, ::IsClipboardFormatAvailable(CF_BITMAP));
+ UIEnable(ID_EDIT_CLEAR, bEnable);
+ UIEnable(ID_VIEW_QUARTERSIZE, true);
+ UIEnable(ID_VIEW_HALFSIZE, true);
+ UIEnable(ID_VIEW_NORMALSIZE, true);
+ UIEnable(ID_VIEW_DOUBLESIZE, true);
+ UIEnable(ID_VIEW_TRIPLESIZE, true);
+ UIEnable(ID_VIEW_QUADRUPLESIZE, true);
+ UIEnable(ID_VIEW_FITTOSCREEN, false); // Not currently implemented.
+ UIEnable(ID_VIEW_FULLSCREEN, false); // Not currently implemented.
+ UIEnable(ID_VIEW_PROPERTIES, bEnable);
+ UIEnable(ID_VIEW_ROTATE0, true);
+ UIEnable(ID_VIEW_ROTATE90, true);
+ UIEnable(ID_VIEW_ROTATE180, true);
+ UIEnable(ID_VIEW_ROTATE270, true);
+ UIEnable(ID_VIEW_MIRROR_HORIZONTAL, true);
+ UIEnable(ID_VIEW_MIRROR_VERTICAL, true);
+ UIEnable(ID_PLAY_PLAY_PAUSE, bMovieOpen); // If no movie open.
+ UIEnable(ID_PLAY_STEP_FORWARD, bMovieOpen);
+ UIEnable(ID_PLAY_STEP_BACKWARD, bMovieOpen);
+ UIEnable(ID_PLAY_GOTO_START, bMovieOpen);
+ UIEnable(ID_PLAY_GOTO_END, bMovieOpen);
+ UIEnable(ID_PLAY_GOTO_FRAME, false); // Not working yet.
+ UIEnable(ID_PLAY_HALFSPEED, true);
+ UIEnable(ID_PLAY_NORMALSPEED, true);
+ UIEnable(ID_PLAY_DOUBLESPEED, true);
+ UIEnable(ID_PLAY_TRIPLESPEED, true);
+ UIEnable(ID_PLAY_QUADRUPLESPEED, true);
+ UIEnable(ID_PLAY_EIGHTSPEED, true);
+ UIEnable(ID_PLAY_SIXTEENSPEED, true);
+ UIEnable(ID_OPTIONS_EXIT, true); // Not currently implemented.
+ UIEnable(ID_OPTIONS_DRAW, true);
+ UIEnable(ID_OPTIONS_AUDIO, !bMovieOpen); // Disable while playing.
+ UIEnable(ID_OPTIONS_DUMPYUVFILE, true);
+
+ UISetCheck(ID_RECENT_BTN, m_list.IsWindowVisible());
+ UIUpdateToolBar();
+
+ return FALSE;
+ }
+
+ void TogglePrintPreview() {
+ if (m_bPrintPreview) { // Close it.
+ ATLASSERT(m_hWndClient == m_wndPreview.m_hWnd);
+
+ m_hWndClient = m_view;
+ m_view.ShowWindow(SW_SHOW);
+ m_wndPreview.DestroyWindow();
+ } else { // display it
+ ATLASSERT(m_hWndClient == m_view.m_hWnd);
+
+ m_wndPreview.SetPrintPreviewInfo(m_printer, m_devmode.m_pDevMode,
+ this, 0, 0);
+ m_wndPreview.SetPage(0);
+
+ m_wndPreview.Create(m_hWnd, rcDefault, NULL, 0, WS_EX_CLIENTEDGE);
+ m_view.ShowWindow(SW_HIDE);
+ m_hWndClient = m_wndPreview;
+ }
+
+ m_bPrintPreview = !m_bPrintPreview;
+ UpdateLayout();
+ }
+
+ void UpdateTitleBar(const wchar_t* lpstrTitle) {
+ CString strDefault;
+ strDefault.LoadString(IDR_MAINFRAME);
+ CString strTitle = strDefault;
+ if (lpstrTitle != NULL) {
+ strTitle = lpstrTitle;
+ strTitle += L" - ";
+ strTitle += strDefault;
+ }
+ SetWindowText(strTitle);
+ }
+
+ // Print job info callbacks.
+ virtual bool IsValidPage(UINT nPage) {
+ return (nPage == 0); // We have only one page.
+ }
+
+ virtual bool PrintPage(UINT nPage, HDC hDC) {
+ if (nPage >= 1) // We have only one page.
+ return false;
+
+ if (m_view.bmp_.IsNull()) // We do not have an image.
+ return false;
+
+ RECT rcPage =
+ { 0, 0,
+ ::GetDeviceCaps(hDC, PHYSICALWIDTH) - 2 *
+ ::GetDeviceCaps(hDC, PHYSICALOFFSETX),
+ ::GetDeviceCaps(hDC, PHYSICALHEIGHT) - 2 *
+ ::GetDeviceCaps(hDC, PHYSICALOFFSETY) };
+
+ CDCHandle dc = hDC;
+ CClientDC dcScreen(m_hWnd);
+ CDC dcMem;
+ dcMem.CreateCompatibleDC(dcScreen);
+ HBITMAP hBmpOld = dcMem.SelectBitmap(m_view.bmp_);
+ int cx = m_view.size_.cx;
+ int cy = m_view.size_.cy;
+
+ // Calc scaling factor, so that bitmap is not too small
+ // based on the width only, max 3/4 width.
+ int nScale = ::MulDiv(rcPage.right, 3, 4) / cx;
+ if (nScale == 0) // too big already
+ nScale = 1;
+ // Calc margines to center bitmap.
+ int xOff = (rcPage.right - nScale * cx) / 2;
+ if (xOff < 0)
+ xOff = 0;
+ int yOff = (rcPage.bottom - nScale * cy) / 2;
+ if (yOff < 0)
+ yOff = 0;
+ // Ensure that preview doesn't go outside of the page.
+ int cxBlt = nScale * cx;
+ if (xOff + cxBlt > rcPage.right)
+ cxBlt = rcPage.right - xOff;
+ int cyBlt = nScale * cy;
+ if (yOff + cyBlt > rcPage.bottom)
+ cyBlt = rcPage.bottom - yOff;
+
+ // Now paint bitmap.
+ dc.StretchBlt(xOff, yOff, cxBlt, cyBlt, dcMem, 0, 0, cx, cy, SRCCOPY);
+
+ dcMem.SelectBitmap(hBmpOld);
+
+ return true;
+ }
+
+ BEGIN_MSG_MAP_EX(CMainFrame)
+ MSG_WM_CREATE(OnCreate)
+ MSG_WM_CONTEXTMENU(OnContextMenu)
+
+ COMMAND_ID_HANDLER_EX(ID_FILE_OPEN, OnFileOpen)
+ COMMAND_ID_HANDLER_EX(ID_FILE_LAST, OnFileLast)
+ COMMAND_RANGE_HANDLER_EX(ID_FILE_MRU_FIRST, ID_FILE_MRU_LAST, OnFileRecent)
+ COMMAND_ID_HANDLER_EX(ID_RECENT_BTN, OnRecentButton)
+ COMMAND_ID_HANDLER_EX(ID_FILE_PRINT, OnFilePrint);
+ COMMAND_ID_HANDLER_EX(ID_FILE_PAGE_SETUP, OnFilePageSetup)
+ COMMAND_ID_HANDLER_EX(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview);
+ COMMAND_ID_HANDLER_EX(ID_APP_EXIT, OnFileExit)
+ COMMAND_ID_HANDLER_EX(ID_EDIT_COPY, OnEditCopy)
+ COMMAND_ID_HANDLER_EX(ID_EDIT_PASTE, OnEditPaste)
+ COMMAND_ID_HANDLER_EX(ID_EDIT_CLEAR, OnEditClear)
+ COMMAND_RANGE_HANDLER_EX(ID_VIEW_QUARTERSIZE, ID_VIEW_FULLSCREEN,
+ OnViewSize)
+ COMMAND_ID_HANDLER_EX(ID_VIEW_TOOLBAR, OnViewToolBar)
+ COMMAND_ID_HANDLER_EX(ID_VIEW_STATUS_BAR, OnViewStatusBar)
+ COMMAND_RANGE_HANDLER_EX(ID_VIEW_ROTATE0, ID_VIEW_MIRROR_VERTICAL,
+ OnViewRotate)
+ COMMAND_ID_HANDLER_EX(ID_VIEW_PROPERTIES, OnViewProperties)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_PLAY_PAUSE, OnPlayPlayPause)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_STEP_FORWARD, OnPlayStepForward)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_STEP_BACKWARD, OnPlayStepBackward)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_GOTO_START, OnPlayGotoStart)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_GOTO_END, OnPlayGotoEnd)
+ COMMAND_ID_HANDLER_EX(ID_PLAY_GOTO_FRAME, OnPlayGotoFrame)
+ COMMAND_RANGE_HANDLER_EX(ID_PLAY_HALFSPEED, ID_PLAY_SIXTEENSPEED,
+ OnPlaySpeed)
+ COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout)
+ COMMAND_ID_HANDLER_EX(ID_OPTIONS_EXIT, OnOptionsExit)
+ COMMAND_ID_HANDLER_EX(ID_OPTIONS_DRAW, OnOptionsDraw)
+ COMMAND_ID_HANDLER_EX(ID_OPTIONS_AUDIO, OnOptionsAudio)
+ COMMAND_ID_HANDLER_EX(ID_OPTIONS_DUMPYUVFILE, OnOptionsDumpYUVFile)
+
+ CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
+ CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
+ END_MSG_MAP()
+
+ BEGIN_UPDATE_UI_MAP(CMainFrame)
+ UPDATE_ELEMENT(ID_FILE_PRINT, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_FILE_PRINT_PREVIEW, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_EDIT_COPY, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_EDIT_PASTE, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_EDIT_CLEAR, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_VIEW_QUARTERSIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_HALFSIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_NORMALSIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_DOUBLESIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_TRIPLESIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_QUADRUPLESIZE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_FITTOSCREEN, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_FULLSCREEN, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_ROTATE0, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_ROTATE90, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_ROTATE180, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_ROTATE270, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_MIRROR_HORIZONTAL, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_MIRROR_VERTICAL, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_VIEW_PROPERTIES, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_PLAY_PLAY_PAUSE, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
+ UPDATE_ELEMENT(ID_PLAY_STEP_FORWARD, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_STEP_BACKWARD, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_GOTO_START, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_GOTO_END, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_GOTO_FRAME, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_HALFSPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_NORMALSPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_DOUBLESPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_TRIPLESPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_QUADRUPLESPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_EIGHTSPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_PLAY_SIXTEENSPEED, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_OPTIONS_EXIT, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_OPTIONS_DRAW, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_OPTIONS_AUDIO, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_OPTIONS_DUMPYUVFILE, UPDUI_MENUPOPUP)
+ UPDATE_ELEMENT(ID_RECENT_BTN, UPDUI_TOOLBAR)
+ END_UPDATE_UI_MAP()
+
+ void UpdateSizeUICheck() {
+ int view_size = m_view.GetViewSize();
+ UISetCheck(ID_VIEW_QUARTERSIZE, (view_size == 0));
+ UISetCheck(ID_VIEW_HALFSIZE, (view_size == 1));
+ UISetCheck(ID_VIEW_NORMALSIZE, (view_size == 2));
+ UISetCheck(ID_VIEW_DOUBLESIZE, (view_size == 3));
+ UISetCheck(ID_VIEW_TRIPLESIZE, (view_size == 4));
+ UISetCheck(ID_VIEW_QUADRUPLESIZE, (view_size == 5));
+ UISetCheck(ID_VIEW_FITTOSCREEN, (view_size == 6));
+ UISetCheck(ID_VIEW_FULLSCREEN, (view_size == 7));
+ }
+
+ void UpdateSpeedUICheck() {
+ if (media::Movie::get()) {
+ float play_rate = media::Movie::get()->GetPlayRate();
+ UISetCheck(ID_PLAY_HALFSPEED, (play_rate == 0.5f));
+ UISetCheck(ID_PLAY_NORMALSPEED, (play_rate == 1.0f));
+ UISetCheck(ID_PLAY_DOUBLESPEED, (play_rate == 2.0f));
+ UISetCheck(ID_PLAY_TRIPLESPEED, (play_rate == 3.0f));
+ UISetCheck(ID_PLAY_QUADRUPLESPEED, (play_rate == 4.0f));
+ UISetCheck(ID_PLAY_EIGHTSPEED, (play_rate == 8.0f));
+ UISetCheck(ID_PLAY_SIXTEENSPEED, (play_rate == 16.0f));
+ }
+ }
+
+ void UpdateRotateUICheck() {
+ int view_rotate = m_view.GetViewRotate();
+ UISetCheck(ID_VIEW_ROTATE0, (view_rotate == 0));
+ UISetCheck(ID_VIEW_ROTATE90, (view_rotate == 1));
+ UISetCheck(ID_VIEW_ROTATE180, (view_rotate == 2));
+ UISetCheck(ID_VIEW_ROTATE270, (view_rotate == 3));
+ UISetCheck(ID_VIEW_MIRROR_HORIZONTAL, (view_rotate == 4));
+ UISetCheck(ID_VIEW_MIRROR_VERTICAL, (view_rotate == 5));
+ }
+
+ int OnCreate(LPCREATESTRUCT /*lpCreateStruct*/) {
+ // create command bar window
+ HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL,
+ ATL_SIMPLE_CMDBAR_PANE_STYLE);
+ // atach menu
+ m_CmdBar.AttachMenu(GetMenu());
+ // load command bar images
+ m_CmdBar.LoadImages(IDR_MAINFRAME);
+ // remove old menu
+ SetMenu(NULL);
+
+ // create toolbar and rebar
+ HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME,
+ FALSE,
+ ATL_SIMPLE_TOOLBAR_PANE_STYLE);
+
+ CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
+ AddSimpleReBarBand(hWndCmdBar);
+ AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
+
+ // create status bar
+ CreateSimpleStatusBar();
+
+ // create view window
+ m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL,
+ WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
+
+ // set up MRU stuff
+ CMenuHandle menu = m_CmdBar.GetMenu();
+ CMenuHandle menuFile = menu.GetSubMenu(FILE_MENU_POSITION);
+ CMenuHandle menuMru = menuFile.GetSubMenu(RECENT_MENU_POSITION);
+ m_mru.SetMenuHandle(menuMru);
+ m_mru.SetMaxEntries(12);
+
+ m_mru.ReadFromRegistry(g_lpcstrMRURegKey);
+
+ // create MRU list
+ m_list.Create(m_hWnd);
+
+ // set up update UI
+ UIAddToolBar(hWndToolBar);
+ UISetCheck(ID_VIEW_NORMALSIZE, 1);
+ UISetCheck(ID_PLAY_NORMALSPEED, 1);
+ UISetCheck(ID_VIEW_TOOLBAR, 1);
+ UISetCheck(ID_VIEW_STATUS_BAR, 1);
+ UISetCheck(ID_VIEW_ROTATE0, 1);
+ UISetCheck(ID_OPTIONS_EXIT, 0);
+ UISetCheck(ID_OPTIONS_DRAW, 1);
+ UISetCheck(ID_OPTIONS_AUDIO, 1);
+ UpdateSizeUICheck();
+ UpdateSpeedUICheck();
+
+ CMessageLoop* pLoop = g_module.GetMessageLoop();
+ ATLASSERT(pLoop != NULL);
+ pLoop->AddMessageFilter(this);
+ pLoop->AddIdleHandler(this);
+
+ return 0;
+ }
+
+ void OnContextMenu(CWindow wnd, POINT point) {
+ if (wnd.m_hWnd == m_view.m_hWnd) {
+ CMenu menu;
+ menu.LoadMenu(IDR_CONTEXTMENU);
+ CMenuHandle menuPopup = menu.GetSubMenu(POPUP_MENU_POSITION);
+ m_CmdBar.TrackPopupMenu(menuPopup, TPM_RIGHTBUTTON | TPM_VERTICAL,
+ point.x, point.y);
+ } else {
+ SetMsgHandled(FALSE);
+ }
+ }
+
+ void OnFileExit(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ PostMessage(WM_CLOSE);
+ }
+
+ bool IsMovie(const wchar_t* file_name) {
+ if (_tcsstr(file_name, L".bmp"))
+ return false;
+ return true;
+ }
+
+ bool MovieOpenFile(const wchar_t* file_name) {
+ bool success = false;
+
+ if (m_bPrintPreview)
+ TogglePrintPreview();
+
+ // If a movie is open, close it.
+ media::Movie::get()->Close();
+
+ if (IsMovie(file_name)) {
+ success = media::Movie::get()->Open(file_name, m_view.renderer_);
+ } else {
+ HBITMAP hbmp = NULL;
+ hbmp = (HBITMAP)::LoadImage(NULL, file_name, IMAGE_BITMAP, 0, 0,
+ LR_CREATEDIBSECTION | LR_DEFAULTCOLOR |
+ LR_LOADFROMFILE);
+ if (hbmp) {
+ m_view.SetBitmap(hbmp);
+ success = true;
+ }
+ }
+
+ if (success) {
+ m_mru.AddToList(file_name);
+ m_mru.WriteToRegistry(g_lpcstrMRURegKey);
+ UpdateTitleBar(file_name);
+ // TODO(fbarchard): Move name into view class.
+ lstrcpy(m_szFilePath, file_name);
+ } else {
+ CString strMsg = L"Can't open movie from:\n";
+ strMsg += file_name;
+ ::MessageBeep(MB_ICONERROR);
+ MessageBox(strMsg, g_lpcstrApp, MB_OK | MB_ICONERROR);
+ }
+ return success;
+ }
+
+ void OnFileOpen(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CFileDialog dlg(TRUE, L"bmp", NULL,
+ OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ L"Movie Files (*.mp4;*.ogg;*.ogv)\0"
+ L"*.mp4;*.ogg;*.ogv\0"
+ L"Audio Files (*.mp3;*.m4a)\0*.mp3;*.m4a\0All Files (*.*)\0*.*\0",
+ m_hWnd);
+ if (dlg.DoModal() == IDOK) {
+ MovieOpenFile(dlg.m_szFileName);
+ }
+ }
+
+ void OnFileRecent(UINT /*uNotifyCode*/, int nID, CWindow /*wnd*/) {
+ // Get file name from the MRU list
+ wchar_t file_name[MAX_PATH];
+ if (m_mru.GetFromList(nID, file_name, MAX_PATH)) {
+ MovieOpenFile(file_name);
+ }
+ }
+
+ void OnFileLast(UINT uNotifyCode, int /*nID*/, CWindow wnd) {
+ OnFileRecent(uNotifyCode, ID_FILE_MRU_FIRST, wnd);
+ }
+
+ void OnRecentButton(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ UINT uBandID = ATL_IDW_BAND_FIRST + 1; // toolbar is second added band
+ CReBarCtrl rebar = m_hWndToolBar;
+ int nBandIndex = rebar.IdToIndex(uBandID);
+ REBARBANDINFO rbbi = { 0 };
+ rbbi.cbSize = RunTimeHelper::SizeOf_REBARBANDINFO();
+ rbbi.fMask = RBBIM_CHILD;
+ rebar.GetBandInfo(nBandIndex, &rbbi);
+ CToolBarCtrl wndToolBar = rbbi.hwndChild;
+
+ int nIndex = wndToolBar.CommandToIndex(ID_RECENT_BTN);
+ CRect rect;
+ wndToolBar.GetItemRect(nIndex, rect);
+ wndToolBar.ClientToScreen(rect);
+
+ // Build and display MRU list in a popup
+ m_list.BuildList(m_mru);
+ m_list.ShowList(rect.left, rect.bottom);
+ }
+
+ void OnFilePrint(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CPrintDialog dlg(FALSE);
+ dlg.m_pd.hDevMode = m_devmode.CopyToHDEVMODE();
+ dlg.m_pd.hDevNames = m_printer.CopyToHDEVNAMES();
+ dlg.m_pd.nMinPage = 1;
+ dlg.m_pd.nMaxPage = 1;
+
+ if (dlg.DoModal() == IDOK) {
+ m_devmode.CopyFromHDEVMODE(dlg.m_pd.hDevMode);
+ m_printer.ClosePrinter();
+ m_printer.OpenPrinter(dlg.m_pd.hDevNames, m_devmode.m_pDevMode);
+
+ CPrintJob job;
+ job.StartPrintJob(false, m_printer, m_devmode.m_pDevMode, this,
+ L"MediaPlayer Document", 0, 0,
+ (dlg.PrintToFile() != FALSE));
+ }
+
+ ::GlobalFree(dlg.m_pd.hDevMode);
+ ::GlobalFree(dlg.m_pd.hDevNames);
+ }
+
+ void OnFilePageSetup(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CPageSetupDialog dlg;
+ dlg.m_psd.hDevMode = m_devmode.CopyToHDEVMODE();
+ dlg.m_psd.hDevNames = m_printer.CopyToHDEVNAMES();
+ dlg.m_psd.rtMargin = m_rcMargin;
+
+ if (dlg.DoModal() == IDOK) {
+ if (m_bPrintPreview)
+ TogglePrintPreview();
+
+ m_devmode.CopyFromHDEVMODE(dlg.m_psd.hDevMode);
+ m_printer.ClosePrinter();
+ m_printer.OpenPrinter(dlg.m_psd.hDevNames, m_devmode.m_pDevMode);
+ m_rcMargin = dlg.m_psd.rtMargin;
+ }
+
+ ::GlobalFree(dlg.m_psd.hDevMode);
+ ::GlobalFree(dlg.m_psd.hDevNames);
+ }
+
+ void OnFilePrintPreview(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ TogglePrintPreview();
+ }
+
+ void OnEditCopy(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ if (::OpenClipboard(NULL)) {
+ HBITMAP hBitmapCopy = (HBITMAP)::CopyImage(m_view.bmp_.m_hBitmap,
+ IMAGE_BITMAP, 0, 0, 0);
+ if (hBitmapCopy != NULL)
+ ::SetClipboardData(CF_BITMAP, hBitmapCopy);
+ else
+ MessageBox(L"Can't copy frame", g_lpcstrApp, MB_OK | MB_ICONERROR);
+
+ ::CloseClipboard();
+ } else {
+ MessageBox(L"Can't open clipboard to copy",
+ g_lpcstrApp, MB_OK | MB_ICONERROR);
+ }
+ }
+
+ void OnEditPaste(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ if (m_bPrintPreview)
+ TogglePrintPreview();
+
+ if (::OpenClipboard(NULL)) {
+ HBITMAP hBitmap = (HBITMAP)::GetClipboardData(CF_BITMAP);
+ ::CloseClipboard();
+ if (hBitmap != NULL) {
+ HBITMAP hBitmapCopy = (HBITMAP)::CopyImage(hBitmap, IMAGE_BITMAP,
+ 0, 0, 0);
+ if (hBitmapCopy != NULL) {
+ m_view.SetBitmap(hBitmapCopy);
+ UpdateTitleBar(L"(Clipboard)");
+ m_szFilePath[0] = 0;
+ } else {
+ MessageBox(L"Can't paste frame",
+ g_lpcstrApp, MB_OK | MB_ICONERROR);
+ }
+ } else {
+ MessageBox(L"Can't open frame from the clipboard",
+ g_lpcstrApp, MB_OK | MB_ICONERROR);
+ }
+ } else {
+ MessageBox(L"Can't open clipboard to paste",
+ g_lpcstrApp, MB_OK | MB_ICONERROR);
+ }
+ }
+
+ void OnEditClear(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ if (m_bPrintPreview)
+ TogglePrintPreview();
+
+ media::Movie::get()->Close();
+ m_view.Reset();
+ UpdateTitleBar(NULL);
+ m_szFilePath[0] = 0;
+ }
+
+ void OnViewSize(UINT /*uNotifyCode*/, int nID, CWindow /*wnd*/) {
+ m_view.SetViewSize(nID - ID_VIEW_QUARTERSIZE);
+ UpdateSizeUICheck();
+ UpdateLayout();
+ }
+
+ void OnViewRotate(UINT /*uNotifyCode*/, int nID, CWindow /*wnd*/) {
+ m_view.SetViewRotate(nID - ID_VIEW_ROTATE0);
+ UpdateRotateUICheck();
+ UpdateLayout();
+ }
+
+ void OnViewToolBar(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ static BOOL bNew = TRUE; // initially visible
+ bNew = !bNew;
+ UINT uBandID = ATL_IDW_BAND_FIRST + 1; // toolbar is second added band
+ CReBarCtrl rebar = m_hWndToolBar;
+ int nBandIndex = rebar.IdToIndex(uBandID);
+ rebar.ShowBand(nBandIndex, bNew);
+ UISetCheck(ID_VIEW_TOOLBAR, bNew);
+ UpdateLayout();
+ }
+
+ void OnViewStatusBar(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ BOOL bNew = !::IsWindowVisible(m_hWndStatusBar);
+ ::ShowWindow(m_hWndStatusBar, bNew ? SW_SHOWNOACTIVATE : SW_HIDE);
+ UISetCheck(ID_VIEW_STATUS_BAR, bNew);
+ UpdateLayout();
+ }
+
+ void OnViewProperties(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CBmpProperties prop;
+ if (lstrlen(m_szFilePath) > 0) // we have a file name
+ prop.SetFileInfo(m_szFilePath, NULL);
+ else // must be clipboard then
+ prop.SetFileInfo(NULL, m_view.bmp_.m_hBitmap);
+ prop.DoModal();
+ }
+
+ void OnPlayPlayPause(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ bool paused = !media::Movie::get()->GetPause();
+ media::Movie::get()->SetPause(paused);
+ }
+
+ void OnPlayStepForward(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ float current_position = media::Movie::get()->GetPosition();
+ media::Movie::get()->SetPosition(current_position + 10.0f);
+ }
+
+ void OnPlayStepBackward(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ float current_position = media::Movie::get()->GetPosition();
+ media::Movie::get()->SetPosition(current_position - 10.0f);
+ }
+
+ void OnPlayGotoStart(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ media::Movie::get()->SetPosition(0.0);
+ }
+
+ void OnPlayGotoEnd(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ float current_position = media::Movie::get()->GetDuration();
+ media::Movie::get()->SetPosition(current_position - 30.0f);
+ }
+
+ void SetPlayRate(int play_speed) {
+ if (play_speed == 0) {
+ media::Movie::get()->Play(0.5f);
+ } else if (play_speed == 2) {
+ media::Movie::get()->Play(2.0f);
+ } else if (play_speed == 3) {
+ media::Movie::get()->Play(3.0f);
+ } else if (play_speed == 4) {
+ media::Movie::get()->Play(4.0f);
+ } else if (play_speed == 5) {
+ media::Movie::get()->Play(8.0f);
+ } else if (play_speed == 6) {
+ media::Movie::get()->Play(16.0f);
+ } else {
+ media::Movie::get()->Play(1.0f);
+ }
+ }
+
+ void OnPlaySpeed(UINT /*uNotifyCode*/, int nID, CWindow /*wnd*/) {
+ int play_speed = nID - ID_PLAY_HALFSPEED;
+ SetPlayRate(play_speed);
+ UpdateSpeedUICheck();
+ UpdateLayout();
+ }
+
+ void OnOptionsExit(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ // TODO(fbarchard): Implement when pipeline exposes properties.
+ enable_exit = !enable_exit;
+ UISetCheck(ID_OPTIONS_EXIT, enable_exit);
+ UpdateLayout();
+ }
+
+ void OnOptionsDraw(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ bool enable_draw = !media::Movie::get()->GetDrawEnable();
+ media::Movie::get()->SetDrawEnable(enable_draw);
+ UISetCheck(ID_OPTIONS_DRAW, enable_draw);
+ UpdateLayout();
+ }
+
+ void OnOptionsAudio(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ bool enable_audio = !media::Movie::get()->GetAudioEnable();
+ media::Movie::get()->SetAudioEnable(enable_audio);
+ UISetCheck(ID_OPTIONS_AUDIO, enable_audio);
+ UpdateLayout();
+ }
+
+ void OnOptionsDumpYUVFile(UINT /*uNotify*/, int /*nID*/, CWindow /*wnd*/) {
+ bool enable_dump_yuv_file = !media::Movie::get()->GetDumpYuvFileEnable();
+ media::Movie::get()->SetDumpYuvFileEnable(enable_dump_yuv_file);
+ UISetCheck(ID_OPTIONS_DUMPYUVFILE, enable_dump_yuv_file);
+ UpdateLayout();
+ }
+
+ void OnAppAbout(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CSimpleDialog<IDD_ABOUTBOX> dlg;
+ dlg.DoModal();
+ }
+
+
+ void OnPlayGotoFrame(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wnd*/) {
+ CSeek seek;
+ seek.DoModal();
+ }
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_MAINFRM_H_
diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc
new file mode 100644
index 0000000..b1d957a
--- /dev/null
+++ b/media/tools/player_wtl/movie.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#include "media/tools/player_wtl/movie.h"
+
+#include "base/string_util.h"
+#include "media/base/pipeline_impl.h"
+#include "media/filters/audio_renderer_impl.h"
+#include "media/filters/ffmpeg_audio_decoder.h"
+#include "media/filters/ffmpeg_demuxer.h"
+#include "media/filters/ffmpeg_video_decoder.h"
+#include "media/filters/file_data_source.h"
+#include "media/filters/null_audio_renderer.h"
+#include "media/tools/player_wtl/wtl_renderer.h"
+
+using media::AudioRendererImpl;
+using media::FFmpegAudioDecoder;
+using media::FFmpegDemuxer;
+using media::FFmpegVideoDecoder;
+using media::FileDataSource;
+using media::FilterFactoryCollection;
+using media::PipelineImpl;
+
+namespace media {
+
+Movie::Movie()
+ : enable_audio_(true),
+ enable_draw_(true),
+ enable_dump_yuv_file_(false),
+ enable_pause_(false),
+ max_threads_(0),
+ play_rate_(1.0f),
+ movie_dib_(NULL),
+ movie_hwnd_(0) {
+}
+
+Movie::~Movie() {
+}
+
+bool Movie::IsOpen() {
+ return pipeline_ != NULL;
+}
+
+void Movie::SetFrameBuffer(HBITMAP hbmp, HWND hwnd) {
+ movie_dib_ = hbmp;
+ movie_hwnd_ = hwnd;
+}
+
+bool Movie::Open(const wchar_t* url, WtlVideoRenderer* video_renderer) {
+ // Close previous movie.
+ if (pipeline_) {
+ Close();
+ }
+
+ // Create our filter factories.
+ scoped_refptr<FilterFactoryCollection> factories =
+ new FilterFactoryCollection();
+ factories->AddFactory(FileDataSource::CreateFactory());
+ factories->AddFactory(FFmpegAudioDecoder::CreateFactory());
+ factories->AddFactory(FFmpegDemuxer::CreateFilterFactory());
+ factories->AddFactory(FFmpegVideoDecoder::CreateFactory());
+
+ if (enable_audio_) {
+ factories->AddFactory(AudioRendererImpl::CreateFilterFactory());
+ } else {
+ factories->AddFactory(media::NullAudioRenderer::CreateFilterFactory());
+ }
+ factories->AddFactory(
+ new media::InstanceFilterFactory<WtlVideoRenderer>(video_renderer));
+
+ thread_.reset(new base::Thread("PipelineThread"));
+ thread_->Start();
+ pipeline_ = new PipelineImpl(thread_->message_loop());
+
+ // Create and start our pipeline.
+ pipeline_->Start(factories, WideToUTF8(std::wstring(url)), NULL);
+ while (true) {
+ PlatformThread::Sleep(100);
+ if (pipeline_->IsInitialized())
+ break;
+ if (pipeline_->GetError() != media::PIPELINE_OK)
+ return false;
+ }
+ pipeline_->SetPlaybackRate(play_rate_);
+ return true;
+}
+
+void Movie::Play(float rate) {
+ // Begin playback.
+ if (pipeline_)
+ pipeline_->SetPlaybackRate(enable_pause_ ? 0.0f : rate);
+ if (rate > 0.0f)
+ play_rate_ = rate;
+}
+
+// Get playback rate.
+float Movie::GetPlayRate() {
+ return play_rate_;
+}
+
+// Get movie duration in seconds.
+float Movie::GetDuration() {
+ float duration = 0.f;
+ if (pipeline_)
+ duration = (pipeline_->GetDuration()).InMicroseconds() / 1000000.0f;
+ return duration;
+}
+
+// Get current movie position in seconds.
+float Movie::GetPosition() {
+ float position = 0.f;
+ if (pipeline_)
+ position = (pipeline_->GetCurrentTime()).InMicroseconds() / 1000000.0f;
+ return position;
+}
+
+// Set current movie position in seconds.
+void Movie::SetPosition(float position) {
+ int64 us = static_cast<int64>(position * 1000000);
+ base::TimeDelta time = base::TimeDelta::FromMicroseconds(us);
+ if (pipeline_)
+ pipeline_->Seek(time, NULL);
+}
+
+
+// Set playback pause.
+void Movie::SetPause(bool pause) {
+ enable_pause_ = pause;
+ Play(play_rate_);
+}
+
+// Get playback pause state.
+bool Movie::GetPause() {
+ return enable_pause_;
+}
+
+void Movie::SetAudioEnable(bool enable_audio) {
+ enable_audio_ = enable_audio;
+}
+
+bool Movie::GetAudioEnable() {
+ return enable_audio_;
+}
+
+void Movie::SetDrawEnable(bool enable_draw) {
+ enable_draw_ = enable_draw;
+}
+
+bool Movie::GetDrawEnable() {
+ return enable_draw_;
+}
+
+void Movie::SetDumpYuvFileEnable(bool enable_dump_yuv_file) {
+ enable_dump_yuv_file_ = enable_dump_yuv_file;
+}
+
+bool Movie::GetDumpYuvFileEnable() {
+ return enable_dump_yuv_file_;
+}
+
+// Teardown.
+void Movie::Close() {
+ if (pipeline_) {
+ pipeline_->Stop(NULL);
+ thread_->Stop();
+ pipeline_ = NULL;
+ thread_.reset();
+ }
+}
+
+} // namespace media
diff --git a/media/tools/player_wtl/movie.h b/media/tools/player_wtl/movie.h
new file mode 100644
index 0000000..ed81182
--- /dev/null
+++ b/media/tools/player_wtl/movie.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Movie class for WTL forms to call to control the media pipeline.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_MOVIE_H_
+#define MEDIA_TOOLS_PLAYER_WTL_MOVIE_H_
+
+#include "media/tools/player_wtl/player_wtl.h"
+
+#include "base/scoped_ptr.h"
+#include "base/singleton.h"
+#include "base/thread.h"
+
+class WtlVideoRenderer;
+
+namespace media {
+
+class PipelineImpl;
+
+class Movie : public Singleton<Movie> {
+ public:
+ // Open a movie.
+ bool Open(const wchar_t* url, WtlVideoRenderer* video_renderer);
+
+ // Set playback rate.
+ void Play(float rate);
+
+ // Set playback rate.
+ float GetPlayRate();
+
+ // Get movie duration in seconds.
+ float GetDuration();
+
+ // Get current movie position in seconds.
+ float GetPosition();
+
+ // Set current movie position in seconds.
+ void SetPosition(float position);
+
+ // Set playback pause.
+ void SetPause(bool pause);
+
+ // Get playback pause state.
+ bool GetPause();
+
+ // Set buffer to render into.
+ void SetFrameBuffer(HBITMAP hbmp, HWND hwnd);
+
+ // Close movie.
+ void Close();
+
+ // Query if movie is currently open.
+ bool IsOpen();
+
+ // Enable/Disable audio.
+ void SetAudioEnable(bool enable_audio);
+
+ // Get Enable/Disable audio state.
+ bool GetAudioEnable();
+
+ // Enable/Disable draw.
+ void SetDrawEnable(bool enable_draw);
+
+ // Get Enable/Disable draw state.
+ bool GetDrawEnable();
+
+ // Enable/Disable dump yuv file.
+ void SetDumpYuvFileEnable(bool enable_dump_yuv_file);
+
+ // Get Enable/Disable dump yuv file state.
+ bool GetDumpYuvFileEnable();
+
+ private:
+ // Only allow Singleton to create and delete Movie.
+ friend struct DefaultSingletonTraits<Movie>;
+ Movie();
+ virtual ~Movie();
+
+ scoped_refptr<PipelineImpl> pipeline_;
+ scoped_ptr<base::Thread> thread_;
+
+ bool enable_audio_;
+ bool enable_draw_;
+ bool enable_dump_yuv_file_;
+ bool enable_pause_;
+ int max_threads_;
+ float play_rate_;
+ HBITMAP movie_dib_;
+ HWND movie_hwnd_;
+
+ DISALLOW_COPY_AND_ASSIGN(Movie);
+};
+
+} // namespace media
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_MOVIE_H_
diff --git a/media/tools/player_wtl/player_wtl.cc b/media/tools/player_wtl/player_wtl.cc
new file mode 100644
index 0000000..73abc95
--- /dev/null
+++ b/media/tools/player_wtl/player_wtl.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Stand alone media player application used for testing the media library.
+
+#include "media/tools/player_wtl/player_wtl.h"
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "media/base/pipeline_impl.h"
+#include "media/filters/audio_renderer_impl.h"
+#include "media/filters/ffmpeg_audio_decoder.h"
+#include "media/filters/ffmpeg_demuxer.h"
+#include "media/filters/ffmpeg_video_decoder.h"
+#include "media/filters/file_data_source.h"
+#include "media/tools/player_wtl/mainfrm.h"
+
+// See player_wtl.h to enable timing code by turning on TESTING macro.
+
+namespace switches {
+const wchar_t* const kExit = L"exit";
+} // namespace switches
+
+CAppModule g_module;
+
+int Run(wchar_t* win_cmd_line, int cmd_show) {
+ base::AtExitManager exit_manager;
+
+ // Windows version of Init uses OS to fetch command line.
+ CommandLine::Init(0, NULL);
+ const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+
+ std::vector<std::wstring> filenames(cmd_line->GetLooseValues());
+
+ CMessageLoop the_loop;
+ g_module.AddMessageLoop(&the_loop);
+
+ CMainFrame wnd_main;
+ if (wnd_main.CreateEx() == NULL) {
+ DCHECK(false) << "Main window creation failed!";
+ return 0;
+ }
+
+ wnd_main.ShowWindow(cmd_show);
+
+ if (!filenames.empty()) {
+ const wchar_t* url = filenames[0].c_str();
+ wnd_main.MovieOpenFile(url);
+ }
+
+ if (cmd_line->HasSwitch(switches::kExit)) {
+ wnd_main.OnOptionsExit(0, 0, 0);
+ }
+
+ int result = the_loop.Run();
+
+ media::Movie::get()->Close();
+
+ g_module.RemoveMessageLoop();
+ return result;
+}
+
+int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE /*previous_instance*/,
+ wchar_t* cmd_line, int cmd_show) {
+#ifdef TESTING
+ double player_time_start = GetTime();
+#endif
+ INITCOMMONCONTROLSEX iccx;
+ iccx.dwSize = sizeof(iccx);
+ iccx.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
+ if (!::InitCommonControlsEx(&iccx)) {
+ DCHECK(false) << "Failed to initialize common controls";
+ return 1;
+ }
+ if (FAILED(g_module.Init(NULL, instance))) {
+ DCHECK(false) << "Failed to initialize application module";
+ return 1;
+ }
+ int result = Run(cmd_line, cmd_show);
+
+ g_module.Term();
+#ifdef TESTING
+ double player_time_end = GetTime();
+ char outputbuf[512];
+ _snprintf_s(outputbuf, sizeof(outputbuf),
+ "player time %5.2f ms\n",
+ player_time_end - player_time_start);
+ OutputDebugStringA(outputbuf);
+ printf("%s", outputbuf);
+#endif
+ return result;
+}
diff --git a/media/tools/player_wtl/player_wtl.h b/media/tools/player_wtl/player_wtl.h
new file mode 100644
index 0000000..96a866c
--- /dev/null
+++ b/media/tools/player_wtl/player_wtl.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Stand alone media player application used for testing the media library.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_PLAYER_WTL_H_
+#define MEDIA_TOOLS_PLAYER_WTL_PLAYER_WTL_H_
+
+// Enable timing code by turning on TESTING macro.
+//#define TESTING 1
+
+// ATL and WTL require order dependent includes.
+#include <atlbase.h> // NOLINT
+#include <atlapp.h> // NOLINT
+#include <atlcrack.h> // NOLINT
+#include <atlctrls.h> // NOLINT
+#include <atlctrlw.h> // NOLINT
+#include <atldlgs.h> // NOLINT
+#include <atlframe.h> // NOLINT
+#include <atlmisc.h> // NOLINT
+#include <atlscrl.h> // NOLINT
+#include <winspool.h> // NOLINT
+#include <atlprint.h> // NOLINT
+
+extern CAppModule g_module;
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_PLAYER_WTL_H_
diff --git a/media/tools/player_wtl/player_wtl.ico b/media/tools/player_wtl/player_wtl.ico
new file mode 100644
index 0000000..93d8182
--- /dev/null
+++ b/media/tools/player_wtl/player_wtl.ico
Binary files differ
diff --git a/media/tools/player_wtl/player_wtl.rc b/media/tools/player_wtl/player_wtl.rc
new file mode 100644
index 0000000..68b892a
--- /dev/null
+++ b/media/tools/player_wtl/player_wtl.rc
@@ -0,0 +1,544 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "../chrome/third_party/wtl/include/atlres.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""../chrome/third_party/wtl/include/atlres.h\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME4 TOOLBAR 16, 15
+BEGIN
+ BUTTON ID_PLAY_PLAY_PAUSE
+ SEPARATOR
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_RECENT_BTN
+ SEPARATOR
+ BUTTON ID_FILE_PRINT
+ BUTTON ID_FILE_PRINT_PREVIEW
+ BUTTON ID_FILE_PAGE_SETUP
+ SEPARATOR
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_EDIT_PASTE
+ BUTTON ID_EDIT_CLEAR
+ SEPARATOR
+ BUTTON ID_VIEW_PROPERTIES
+ BUTTON ID_APP_ABOUT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME4 BITMAP "Toolbar.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW
+ MENUITEM "Pa&ge Setup...", ID_FILE_PAGE_SETUP
+ MENUITEM SEPARATOR
+ POPUP "Recent &Files"
+ BEGIN
+ MENUITEM "(empty)", ID_FILE_MRU_FILE1
+ END
+ MENUITEM "&Last...\tCtrl+L", ID_FILE_LAST
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
+ MENUITEM "Cl&ear\tCTRL+F4", ID_EDIT_CLEAR
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Quarter Size\tCtrl+9", ID_VIEW_QUARTERSIZE
+ MENUITEM "&Half Size\tCtrl+0", ID_VIEW_HALFSIZE
+ MENUITEM "&Normal Size\tCtrl+1", ID_VIEW_NORMALSIZE
+ MENUITEM "&Double Size\tCtrl+2", ID_VIEW_DOUBLESIZE
+ MENUITEM "Triple Size\tCtrl+3", ID_VIEW_TRIPLESIZE
+ MENUITEM "Quadruple Size\tCtrl+4", ID_VIEW_QUADRUPLESIZE
+ MENUITEM "Fit to Screen", ID_VIEW_FITTOSCREEN
+ MENUITEM "&Full Screen\tCtrl+F", ID_VIEW_FULLSCREEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ MENUITEM SEPARATOR
+ MENUITEM "N&o Rotation", ID_VIEW_ROTATE0
+ MENUITEM "Rotate &90", ID_VIEW_ROTATE90
+ MENUITEM "Rotate &180", ID_VIEW_ROTATE180
+ MENUITEM "Rotate &270", ID_VIEW_ROTATE270
+ MENUITEM "&Mirror Horizontally", ID_VIEW_MIRROR_HORIZONTAL
+ MENUITEM "Mirror &Vertically", ID_VIEW_MIRROR_VERTICAL
+ MENUITEM SEPARATOR
+ MENUITEM "&Properties", ID_VIEW_PROPERTIES
+ END
+ POPUP "&Play"
+ BEGIN
+ MENUITEM "&Play/Pause\tSpace", ID_PLAY_PLAY_PAUSE
+ MENUITEM "Skip &Forward\tRight Arrow", ID_PLAY_STEP_FORWARD
+ MENUITEM "Skip &Backward\tLeft Arrow", ID_PLAY_STEP_BACKWARD
+ MENUITEM "G&oto Start\tHome", ID_PLAY_GOTO_START
+ MENUITEM "Goto &End\tEnd", ID_PLAY_GOTO_END
+ MENUITEM "&Goto Frame\tCtrl+G", ID_PLAY_GOTO_FRAME
+ MENUITEM SEPARATOR
+ MENUITEM "&Half Speed\tAlt+0", ID_PLAY_HALFSPEED
+ MENUITEM "&Normal Speed\tAlt+1", ID_PLAY_NORMALSPEED
+ MENUITEM "&Double Speed\tAlt+2", ID_PLAY_DOUBLESPEED
+ MENUITEM "&Triple Speed\tAlt+3", ID_PLAY_TRIPLESPEED
+ MENUITEM "&Quadruple Speed\tAlt+4", ID_PLAY_QUADRUPLESPEED
+ MENUITEM "&Eight Times Speed\tAlt+5", ID_PLAY_EIGHTSPEED
+ MENUITEM "&Sixteen Times Speed\tAlt+6", ID_PLAY_SIXTEENSPEED
+ END
+ POPUP "&Options"
+ BEGIN
+ MENUITEM "&Exit at End of Movie", ID_OPTIONS_EXIT
+ MENUITEM "Draw", ID_OPTIONS_DRAW
+ MENUITEM "Audio", ID_OPTIONS_AUDIO
+ MENUITEM "Dump YUV File", ID_OPTIONS_DUMPYUVFILE
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About Media Player...", ID_APP_ABOUT
+ END
+END
+
+IDR_CONTEXTMENU MENU
+BEGIN
+ POPUP ""
+ BEGIN
+ MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
+ MENUITEM "Cl&ear", ID_EDIT_CLEAR
+ MENUITEM SEPARATOR
+ MENUITEM "&Properties", ID_VIEW_PROPERTIES
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME3 ICON "player_wtl.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 185, 126
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,121,97,50,14
+ CTEXT "Media Player\n\nAugust 11, 2009\n\nCopyright (c) 2009 The Chromium Authors.\nAll rights reserved.",IDC_STATIC,7,43,171,49
+ ICON IDR_MAINFRAME3,IDC_STATIC,80,17,20,20
+ GROUPBOX "",IDC_STATIC,7,7,171,112
+END
+
+IDD_PROP_PAGE1 DIALOGEX 0, 0, 212, 114
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Movie"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ LTEXT "Location:",IDC_STATIC,5,20,30,8
+ LTEXT "Size:",IDC_STATIC,5,34,16,8
+ LTEXT "Created:",IDC_STATIC,5,65,28,8
+ LTEXT "Attributes:",IDC_STATIC,5,81,32,8
+ LTEXT "Static",IDC_FILESIZE,40,34,170,8
+ LTEXT "Static",IDC_FILEDATE,40,65,165,8
+ LTEXT "Static",IDC_FILEATTRIB,40,81,170,8
+ LTEXT "Static",IDC_FILELOCATION,40,20,170,8,SS_NOTIFY
+ LTEXT "Duration:",IDC_STATIC,5,49,30,8
+ LTEXT "Static",IDC_FILEDURATION,40,50,170,8
+END
+
+IDD_PROP_PAGE2 DIALOGEX 0, 0, 212, 114
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Frame"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ LTEXT "Type:",IDC_STATIC,15,10,80,8
+ LTEXT "Static",IDC_TYPE,100,10,105,8
+ LTEXT "Width:",IDC_STATIC,15,25,80,8
+ LTEXT "Static",IDC_WIDTH,100,25,105,8
+ LTEXT "Height:",IDC_STATIC,15,40,80,8
+ LTEXT "Static",IDC_HEIGHT,100,40,105,8
+ LTEXT "Horizontal Resolution:",IDC_STATIC,15,55,80,8
+ LTEXT "Static",IDC_HORRES,100,55,105,8
+ LTEXT "Vertical Resolution:",IDC_STATIC,15,70,80,8
+ LTEXT "Static",IDC_VERTRES,100,70,105,8
+ LTEXT "Bit Depth:",IDC_STATIC,15,85,80,8
+ LTEXT "Static",IDC_BITDEPTH,100,85,105,8
+ LTEXT "Compression:",IDC_STATIC,15,100,80,8
+ LTEXT "Static",IDC_COMPRESSION,100,100,105,8
+END
+
+IDD_PROP_PAGE3 DIALOGEX 0, 0, 212, 114
+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION
+CAPTION "Screen"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ LTEXT "Width:",IDC_STATIC,15,25,80,8
+ LTEXT "Static",IDC_WIDTH,100,25,105,8
+ LTEXT "Height:",IDC_STATIC,15,40,80,8
+ LTEXT "Static",IDC_HEIGHT,100,40,105,8
+ LTEXT "Horizontal DPI:",IDC_STATIC,15,55,80,8
+ LTEXT "Static",IDC_HORRES,100,55,105,8
+ LTEXT "Vertical DPI:",IDC_STATIC,15,70,80,8
+ LTEXT "Static",IDC_VERTRES,100,70,105,8
+ LTEXT "Bit Depth:",IDC_STATIC,15,85,80,8
+ LTEXT "Static",IDC_BITDEPTH,100,85,105,8
+END
+
+IDD_SEEK DIALOGEX 0, 0, 664, 55
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Seek"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_SEEKSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,7,27,650,21
+ LTEXT "Location:",IDC_STATIC,15,14,30,8
+ LTEXT "Static",IDC_SEEKLOCATION,50,15,170,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 178
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 119
+ END
+
+ IDD_PROP_PAGE1, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 205
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 107
+ END
+
+ IDD_PROP_PAGE2, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 205
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 107
+ END
+
+ IDD_PROP_PAGE3, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 205
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 107
+ END
+
+ IDD_SEEK, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 657
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 48
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME2 ACCELERATORS
+BEGIN
+ VK_F4, ID_EDIT_CLEAR, VIRTKEY, CONTROL, NOINVERT
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "L", ID_FILE_LAST, VIRTKEY, CONTROL, NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
+ "2", ID_PLAY_DOUBLESPEED, VIRTKEY, ALT, NOINVERT
+ "5", ID_PLAY_EIGHTSPEED, VIRTKEY, ALT, NOINVERT
+ "G", ID_PLAY_GOTO_FRAME, VIRTKEY, CONTROL, NOINVERT
+ "0", ID_PLAY_HALFSPEED, VIRTKEY, ALT, NOINVERT
+ "1", ID_PLAY_NORMALSPEED, VIRTKEY, ALT, NOINVERT
+ " ", ID_PLAY_PLAY_PAUSE, ASCII, NOINVERT
+ "4", ID_PLAY_QUADRUPLESPEED, VIRTKEY, ALT, NOINVERT
+ "6", ID_PLAY_SIXTEENSPEED, VIRTKEY, ALT, NOINVERT
+ VK_LEFT, ID_PLAY_STEP_BACKWARD, VIRTKEY, NOINVERT
+ VK_RIGHT, ID_PLAY_STEP_FORWARD, VIRTKEY, NOINVERT
+ "3", ID_PLAY_TRIPLESPEED, VIRTKEY, ALT, NOINVERT
+ "2", ID_VIEW_DOUBLESIZE, VIRTKEY, CONTROL, NOINVERT
+ "F", ID_VIEW_FULLSCREEN, VIRTKEY, CONTROL, NOINVERT
+ "0", ID_VIEW_HALFSIZE, VIRTKEY, CONTROL, NOINVERT
+ "1", ID_VIEW_NORMALSIZE, VIRTKEY, CONTROL, NOINVERT
+ "4", ID_VIEW_QUADRUPLESIZE, VIRTKEY, CONTROL, NOINVERT
+ "9", ID_VIEW_QUARTERSIZE, VIRTKEY, CONTROL, NOINVERT
+ "3", ID_VIEW_TRIPLESIZE, VIRTKEY, CONTROL, NOINVERT
+ VK_HOME, ID_PLAY_GOTO_START, VIRTKEY, NOINVERT
+ VK_END, ID_PLAY_GOTO_END, VIRTKEY, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Written by Frank Barchard"
+ VALUE "FileDescription", "media_player"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "media_player_wtl"
+ VALUE "LegalCopyright", "Copyright 2009"
+ VALUE "OriginalFilename", "media_player_wtl.exe"
+ VALUE "ProductName", "media_player"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "Media Player"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_NEW "Create a new document\nNew"
+ ID_FILE_OPEN "Open a movie\nOpen"
+ ID_FILE_CLOSE "Close movie\nClose"
+ ID_FILE_SAVE "Save the movie\nSave"
+ ID_FILE_SAVE_AS "Save the movie with a new name\nSave As"
+ ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
+ ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
+ ID_FILE_PRINT "Print the movie\nPrint"
+ ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_HALFSIZE "View movie at half normal size."
+ ID_VIEW_NORMALSIZE "View movie at normal size."
+ ID_VIEW_DOUBLESIZE "View movie at twice the normal size."
+ ID_VIEW_TRIPLESIZE "View movie at triple the normal size."
+ ID_VIEW_QUADRUPLESIZE "View movie at quadruple the normal size."
+ ID_VIEW_FITTOSCREEN "Maximize window to desktop."
+ ID_VIEW_FULLSCREEN "Full screen mode."
+ ID_PLAY_HALFSPEED "Play movie at half normal speed."
+ ID_PLAY_NORMALSPEED "Play movie at normal speed."
+ ID_PLAY_DOUBLESPEED "Play movie at twice the normal speed."
+ ID_PLAY_TRIPLESPEED "Play movie at triple the normal speed."
+ ID_PLAY_QUADRUPLESPEED "Play movie at quadruple the normal speed."
+ ID_PLAY_EIGHTSPEED "Play movie at eight times the normal speed."
+ ID_PLAY_SIXTEENSPEED "Play movie at sixteen times the normal speed."
+ ID_PLAY_STEP_FORWARD "Step forward one frame."
+ ID_PLAY_STEP_BACKWARD "Step backward one frame."
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_LAST "Replay last movie\nOpen"
+ ID_VIEW_ROTATE0 "Turn off rotation."
+ ID_VIEW_ROTATE90 "Rotate movie by 90 degrees clockwise."
+ ID_VIEW_ROTATE180 "Rotate movie by 180 degrees."
+ ID_VIEW_ROTATE270 "Rotate movie by 270 degrees clockwise."
+ ID_VIEW_MIRROR_HORIZONTAL "Mirror movie horizontally."
+ ID_VIEW_MIRROR_VERTICAL "Mirror movie vertically."
+ ID_VIEW_QUARTERSIZE "View movie at quarter normal size."
+END
+
+STRINGTABLE
+BEGIN
+ ID_RECENT_BTN "\nRecent Files"
+ ID_VIEW_PROPERTIES "Displays movie properties\nProperties"
+ ID_PLAY_PLAY_PAUSE "Start or pause movie playback"
+END
+
+STRINGTABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
+ ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
+END
+
+STRINGTABLE
+BEGIN
+ ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
+ ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
+ ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
+END
+
+STRINGTABLE
+BEGIN
+ ID_WINDOW_NEW "Open another window for the movie\nNew Window"
+ ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
+ ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows"
+ ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_EDIT_CLEAR "Removes the movie\nClear"
+ ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
+ ID_EDIT_COPY "Copy the movie and put it on the Clipboard\nCopy"
+ ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
+ ID_EDIT_FIND "Find the specified text\nFind"
+ ID_EDIT_PASTE "Insert movie from the Clipboard\nPaste"
+ ID_EDIT_REPEAT "Repeat the last action\nRepeat"
+ ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
+ ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
+ ID_EDIT_UNDO "Undo the last action\nUndo"
+ ID_EDIT_REDO "Redo the previously undone action\nRedo"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_SCSIZE "Change the window size"
+ ATL_IDS_SCMOVE "Change the window position"
+ ATL_IDS_SCMINIMIZE "Reduce the window to an icon"
+ ATL_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ ATL_IDS_SCNEXTWINDOW "Switch to the next document window"
+ ATL_IDS_SCPREVWINDOW "Switch to the previous document window"
+ ATL_IDS_SCCLOSE "Close the active window and prompts to save the documents"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_SCRESTORE "Restore the window to normal size"
+ ATL_IDS_SCTASKLIST "Activate Task List"
+ ATL_IDS_MDICHILD "Activate this window"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_IDLEMESSAGE "Ready"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_MRU_FILE "Open this document"
+END
+
+STRINGTABLE
+BEGIN
+ ID_PLAY_GOTO_FRAME "Goto a specified frame in the movie."
+ ID_PLAY_GOTO_START "Goto to start of movie."
+ ID_PLAY_GOTO_END "Goto end of movie minus 30 seconds."
+ ID_OPTIONS_EXIT "Exit player at end of movie."
+END
+
+STRINGTABLE
+BEGIN
+ ID_OPTIONS_DRAW "Enable/Disable Draws"
+ ID_OPTIONS_AUDIO "Enable/Disable Audio"
+ ID_OPTIONS_DUMPYUVFILE "Dump YUV frames to a file"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/media/tools/player_wtl/props.h b/media/tools/player_wtl/props.h
new file mode 100644
index 0000000..65224e5
--- /dev/null
+++ b/media/tools/player_wtl/props.h
@@ -0,0 +1,325 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_PROPS_H_
+#define MEDIA_TOOLS_PLAYER_WTL_PROPS_H_
+
+#include "media/tools/player_wtl/movie.h"
+
+#include "resource.h"
+
+// Movie properties dialog
+class CFileName : public CWindowImpl<CFileName> {
+ public:
+
+ CFileName() : file_name_(NULL) {
+ }
+
+ void Init(HWND hwnd, wchar_t* str_name) {
+ ATLASSERT(::IsWindow(hwnd));
+ SubclassWindow(hwnd);
+
+ // Set tooltip.
+ tooltip_.Create(m_hWnd);
+ ATLASSERT(tooltip_.IsWindow());
+ RECT rect;
+ GetClientRect(&rect);
+ CToolInfo ti(0, m_hWnd, tooltip_id_, &rect, NULL);
+ tooltip_.AddTool(&ti);
+
+ // Set text.
+ file_name_ = str_name;
+ if (file_name_ == NULL)
+ return;
+
+ CClientDC dc(m_hWnd); // will not really paint
+ HFONT old_font = dc.SelectFont(AtlGetDefaultGuiFont());
+
+ RECT rect_text = rect;
+ dc.DrawText(file_name_, -1, &rect_text,
+ DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_NOPREFIX |
+ DT_CALCRECT);
+ BOOL is_too_long = (rect_text.right > rect.right);
+ if (is_too_long)
+ tooltip_.UpdateTipText(file_name_, m_hWnd, tooltip_id_);
+ tooltip_.Activate(is_too_long);
+
+ dc.SelectFont(old_font);
+
+ Invalidate();
+ UpdateWindow();
+ }
+
+ BEGIN_MSG_MAP(CFileName)
+ MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
+ MESSAGE_HANDLER(WM_PAINT, OnPaint)
+ END_MSG_MAP()
+
+ LRESULT OnMouseMessage(UINT message, WPARAM wparam, LPARAM lparam,
+ BOOL& handled) {
+ if (tooltip_.IsWindow()) {
+ MSG msg = { m_hWnd, message, wparam, lparam };
+ tooltip_.RelayEvent(&msg);
+ }
+ handled = FALSE;
+ return 1;
+ }
+
+ LRESULT OnPaint(UINT /*message*/, WPARAM /*wparam*/, LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ CPaintDC dc(m_hWnd);
+ if (file_name_ != NULL) {
+ RECT rect;
+ GetClientRect(&rect);
+
+ dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
+ dc.SetBkMode(TRANSPARENT);
+ HFONT old_font = dc.SelectFont(AtlGetDefaultGuiFont());
+
+ dc.DrawText(file_name_, -1, &rect, DT_SINGLELINE | DT_LEFT |
+ DT_VCENTER | DT_NOPREFIX | DT_PATH_ELLIPSIS);
+
+ dc.SelectFont(old_font);
+ }
+ return 0;
+ }
+
+ DECLARE_WND_CLASS_EX(NULL, 0, COLOR_3DFACE)
+
+ wchar_t* file_name_;
+
+ enum { tooltip_id_ = 1313 };
+ CToolTipCtrl tooltip_;
+};
+
+// Movie properties.
+// TODO(fbarchard): Add movie duration in seconds.
+class CPageOne : public CPropertyPageImpl<CPageOne> {
+ public:
+ enum { IDD = IDD_PROP_PAGE1 };
+
+ CPageOne() : file_name_(NULL) {
+ }
+
+ BEGIN_MSG_MAP(CPageOne)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ CHAIN_MSG_MAP(CPropertyPageImpl<CPageOne>)
+ END_MSG_MAP()
+
+ LRESULT OnInitDialog(UINT /*message*/, WPARAM /*wparam*/, LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ if (file_name_ != NULL) {
+ file_location_.Init(GetDlgItem(IDC_FILELOCATION), file_name_);
+
+ WIN32_FIND_DATA find_data;
+ HANDLE find_handle = ::FindFirstFile(file_name_, &find_data);
+ if (find_handle != INVALID_HANDLE_VALUE) {
+ // TODO(fbarchard): Support files larger than 2 GB
+ int size_k = (find_data.nFileSizeLow / 1024);
+ if (size_k == 0 && find_data.nFileSizeLow != 0)
+ size_k = 1;
+ wchar_t szBuff[100];
+ wsprintf(szBuff, L"%i KB", size_k);
+ SetDlgItemText(IDC_FILESIZE, szBuff);
+
+ // TODO(fbarchard): We need a pipeline property for frame rate.
+ float duration = media::Movie::get()->GetDuration();
+ float fps = 29.97f;
+ wsprintf(szBuff, L"%i.%2i Seconds, %i Frames",
+ static_cast<int>(duration),
+ static_cast<int>(duration * 100) % 100,
+ static_cast<int>(duration * fps));
+ SetDlgItemText(IDC_FILEDURATION, szBuff);
+
+ SYSTEMTIME st;
+ ::FileTimeToSystemTime(&find_data.ftCreationTime, &st);
+ ::GetDateFormat(LOCALE_USER_DEFAULT, 0, &st,
+ L"dddd, MMMM dd',' yyyy',' ",
+ szBuff, sizeof(szBuff) / sizeof(szBuff[0]));
+ wchar_t szBuff1[50];
+ ::GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st,
+ L"hh':'mm':'ss tt", szBuff1,
+ sizeof(szBuff1) / sizeof(szBuff1[0]));
+ lstrcat(szBuff, szBuff1);
+ SetDlgItemText(IDC_FILEDATE, szBuff);
+
+ szBuff[0] = 0;
+ if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0)
+ lstrcat(szBuff, L"Archive, ");
+ if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0)
+ lstrcat(szBuff, L"Read-only, ");
+ if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)
+ lstrcat(szBuff, L"Hidden, ");
+ if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0)
+ lstrcat(szBuff, L"System");
+ int length = lstrlen(szBuff);
+ if (length >= 2 && szBuff[length - 2] == L',')
+ szBuff[length - 2] = 0;
+ SetDlgItemText(IDC_FILEATTRIB, szBuff);
+
+ ::FindClose(find_handle);
+ }
+ } else {
+ SetDlgItemText(IDC_FILELOCATION, L"(Clipboard)");
+ SetDlgItemText(IDC_FILESIZE, L"N/A");
+ SetDlgItemText(IDC_FILEDATE, L"N/A");
+ SetDlgItemText(IDC_FILEATTRIB, L"N/A");
+ }
+ return TRUE;
+ }
+
+ CFileName file_location_;
+ wchar_t* file_name_;
+};
+
+// Frame properties.
+// TODO(fbarchard): This is not implemented for movies yet.
+class CPageTwo : public CPropertyPageImpl<CPageTwo> {
+ public:
+ enum { IDD = IDD_PROP_PAGE2 };
+
+ CPageTwo() : file_name_(NULL) {
+ }
+
+ BEGIN_MSG_MAP(CPageTwo)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ CHAIN_MSG_MAP(CPropertyPageImpl<CPageTwo>)
+ END_MSG_MAP()
+
+ LRESULT OnInitDialog(UINT /*message*/, WPARAM /*wparam*/, LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ // Special - remove unused buttons, move Close button, center wizard
+ CPropertySheetWindow sheet = GetPropertySheet();
+#if !defined(_AYGSHELL_H_) && !defined(__AYGSHELL_H__) // PPC specific.
+ sheet.CancelToClose();
+ RECT rect;
+ CButton btn_cancel = sheet.GetDlgItem(IDCANCEL);
+ btn_cancel.GetWindowRect(&rect);
+ sheet.ScreenToClient(&rect);
+ btn_cancel.ShowWindow(SW_HIDE);
+ CButton btn_close = sheet.GetDlgItem(IDOK);
+ btn_close.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOSIZE);
+ sheet.CenterWindow(GetPropertySheet().GetParent());
+
+ sheet.ModifyStyleEx(WS_EX_CONTEXTHELP, 0);
+#endif // (_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific.
+
+ // Get and display movie prperties.
+ SetDlgItemText(IDC_TYPE, L"MP4 Movie");
+ wchar_t* compression_text = L"H.264";
+
+ if (file_name_ != NULL) {
+ HANDLE file_handle = ::CreateFile(file_name_, GENERIC_READ,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL |
+ FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ ATLASSERT(file_handle != INVALID_HANDLE_VALUE);
+ if (file_handle != INVALID_HANDLE_VALUE) {
+ DWORD dwRead = 0;
+ BITMAPFILEHEADER bfh;
+ ::ReadFile(file_handle, &bfh, sizeof(bfh), &dwRead, NULL);
+ BITMAPINFOHEADER bih;
+ ::ReadFile(file_handle, &bih, sizeof(bih), &dwRead, NULL);
+ ::CloseHandle(file_handle);
+
+ SetDlgItemInt(IDC_WIDTH, bih.biWidth);
+ SetDlgItemInt(IDC_HEIGHT, bih.biHeight);
+ SetDlgItemInt(IDC_HORRES, ::MulDiv(bih.biXPelsPerMeter, 254, 10000));
+ SetDlgItemInt(IDC_VERTRES, ::MulDiv(bih.biYPelsPerMeter, 254, 10000));
+ SetDlgItemInt(IDC_BITDEPTH, bih.biBitCount);
+
+ switch (bih.biCompression) {
+ case BI_RLE4:
+ case BI_RLE8:
+ compression_text = L"RLE";
+ break;
+ case BI_BITFIELDS:
+ compression_text = L"Uncompressed with bitfields";
+ break;
+ case BI_JPEG:
+ case BI_PNG:
+ compression_text = L"Unknown";
+ break;
+ }
+ SetDlgItemText(IDC_COMPRESSION, compression_text);
+ }
+ } else { // Must be pasted from the clipboard.
+ ATLASSERT(!bmp_.IsNull());
+ BITMAP bitmap = { 0 };
+ bool result = bmp_.GetBitmap(bitmap);
+ ATLASSERT(result);
+ if (result) {
+ CClientDC dc(NULL);
+ SetDlgItemInt(IDC_WIDTH, bitmap.bmWidth);
+ SetDlgItemInt(IDC_HEIGHT, bitmap.bmHeight);
+ // Should we use screen resolution here???
+ SetDlgItemInt(IDC_HORRES, dc.GetDeviceCaps(LOGPIXELSX));
+ SetDlgItemInt(IDC_VERTRES, dc.GetDeviceCaps(LOGPIXELSX));
+ SetDlgItemInt(IDC_BITDEPTH, bitmap.bmBitsPixel);
+ SetDlgItemText(IDC_COMPRESSION, compression_text);
+ }
+ }
+ return TRUE;
+ }
+
+ CBitmapHandle bmp_;
+ wchar_t* file_name_;
+};
+
+// Screen properties.
+class CPageThree : public CPropertyPageImpl<CPageThree> {
+ public:
+ enum { IDD = IDD_PROP_PAGE3 };
+
+ BEGIN_MSG_MAP(CPageThree)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ CHAIN_MSG_MAP(CPropertyPageImpl<CPageThree>)
+ END_MSG_MAP()
+
+ LRESULT OnInitDialog(UINT /*message*/, WPARAM /*wparam*/, LPARAM /*lparam*/,
+ BOOL& /*handled*/) {
+ // Get and set screen properties.
+ CClientDC dc(NULL);
+ SetDlgItemInt(IDC_WIDTH, dc.GetDeviceCaps(HORZRES));
+ SetDlgItemInt(IDC_HEIGHT, dc.GetDeviceCaps(VERTRES));
+ SetDlgItemInt(IDC_HORRES, dc.GetDeviceCaps(LOGPIXELSX));
+ SetDlgItemInt(IDC_VERTRES, dc.GetDeviceCaps(LOGPIXELSY));
+ SetDlgItemInt(IDC_BITDEPTH, dc.GetDeviceCaps(BITSPIXEL));
+
+ return TRUE;
+ }
+};
+
+// TODO(fbachard): Frame properties only work for images, so
+// this tab is removed until movie frame properties can be
+// added.
+class CBmpProperties : public CPropertySheetImpl<CBmpProperties> {
+ public:
+
+ CBmpProperties() {
+ m_psh.dwFlags |= PSH_NOAPPLYNOW;
+
+ AddPage(page1_);
+ // AddPage(page2_); // Not implemented for movies yet.
+ AddPage(page3_);
+ SetActivePage(0);
+ SetTitle(L"Movie Properties");
+ }
+
+ void SetFileInfo(wchar_t* file_path, HBITMAP bitmap) {
+ page1_.file_name_ = file_path;
+ page2_.file_name_ = file_path;
+ page2_.bmp_ = bitmap;
+ }
+
+ BEGIN_MSG_MAP(CBmpProperties)
+ CHAIN_MSG_MAP(CPropertySheetImpl<CBmpProperties>)
+ END_MSG_MAP()
+
+ CPageOne page1_;
+ CPageTwo page2_;
+ CPageThree page3_;
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_PROPS_H_
diff --git a/media/tools/player_wtl/resource.h b/media/tools/player_wtl/resource.h
new file mode 100644
index 0000000..4c4b643
--- /dev/null
+++ b/media/tools/player_wtl/resource.h
@@ -0,0 +1,78 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by player_wtl.rc
+//
+#define IDD_ABOUTBOX 100
+#define IDR_MAINFRAME 128
+#define IDR_MAINFRAME2 128
+#define IDR_MAINFRAME3 128
+#define IDR_MAINFRAME4 128
+#define IDR_CONTEXTMENU 201
+#define IDD_PROP_PAGE1 202
+#define IDD_PROP_PAGE2 203
+#define IDD_PROP_PAGE3 204
+#define IDD_SEEK 205
+#define IDC_TYPE 1001
+#define IDC_WIDTH 1002
+#define IDC_HEIGHT 1003
+#define IDC_HORRES 1004
+#define IDC_VERTRES 1005
+#define IDC_BITDEPTH 1006
+#define IDC_COMPRESSION 1008
+#define IDC_FILELOCATION 1009
+#define IDC_FILESIZE 1010
+#define IDC_FILEDATE 1011
+#define IDC_FILEATTRIB 1012
+#define IDC_FILEDURATION 1013
+#define IDC_SEEKSLIDER 1013
+#define IDC_SEEKLOCATION 1014
+#define ID_RECENT_BTN 32777
+#define ID_VIEW_PROPERTIES 32778
+#define ID_VIEW_MEDIADETAILS 32780
+#define ID_PLAY_PLAY 32781
+#define ID_PLAY_PLAY_PAUSE 32782
+#define ID_OPTIONS_EXIT 32840
+#define ID_OPTIONS_DRAW 32792
+#define ID_OPTIONS_AUDIO 32793
+#define ID_OPTIONS_DUMPYUVFILE 32794
+#define ID_Menu 32795
+#define ID_FILE_LAST 32804
+#define ID_Menu32806 32806
+#define ID_VIEW_ROTATE0 32807
+#define ID_VIEW_ROTATE90 32808
+#define ID_VIEW_ROTATE180 32809
+#define ID_VIEW_ROTATE270 32810
+#define ID_VIEW_MIRROR_HORIZONTAL 32811
+#define ID_VIEW_MIRROR_VERTICAL 32812
+#define ID_VIEW_QUARTERSIZE 32815
+#define ID_VIEW_HALFSIZE 32816
+#define ID_VIEW_NORMALSIZE 32817
+#define ID_VIEW_DOUBLESIZE 32818
+#define ID_VIEW_TRIPLESIZE 32819
+#define ID_VIEW_QUADRUPLESIZE 32820
+#define ID_VIEW_FITTOSCREEN 32821
+#define ID_VIEW_FULLSCREEN 32822
+#define ID_PLAY_HALFSPEED 32823
+#define ID_PLAY_NORMALSPEED 32824
+#define ID_PLAY_DOUBLESPEED 32825
+#define ID_PLAY_TRIPLESPEED 32826
+#define ID_PLAY_QUADRUPLESPEED 32827
+#define ID_PLAY_EIGHTSPEED 32828
+#define ID_PLAY_SIXTEENSPEED 32829
+#define ID_PLAY_STEP_FORWARD 32830
+#define ID_PLAY_STEP_BACKWARD 32831
+#define ID_PLAY_GOTO_FRAME 32836
+#define ID_PLAY_GOTO_START 32838
+#define ID_PLAY_GOTO_END 32839
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 206
+#define _APS_NEXT_COMMAND_VALUE 32842
+#define _APS_NEXT_CONTROL_VALUE 1014
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/media/tools/player_wtl/seek.h b/media/tools/player_wtl/seek.h
new file mode 100644
index 0000000..84f3c95
--- /dev/null
+++ b/media/tools/player_wtl/seek.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_SEEK_H_
+#define MEDIA_TOOLS_PLAYER_WTL_SEEK_H_
+
+#include "media/tools/player_wtl/player_wtl.h"
+
+// Movie seek dialog.
+// TODO(fbachard): Frame properties only work for images, so
+// this tab is removed until movie frame properties can be added.
+class CSeek : public CSimpleDialog<IDD_SEEK>,
+ public CMessageFilter,
+ public CIdleHandler {
+ public:
+ CSeek() {
+ }
+
+ virtual BOOL PreTranslateMessage(MSG* pMsg) {
+ return FALSE;
+ }
+
+ BEGIN_MSG_MAP(CSeek)
+ MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
+ MESSAGE_HANDLER(WM_PAINT, OnPaint)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ CHAIN_MSG_MAP(CSimpleDialog<IDD_SEEK>)
+ END_MSG_MAP()
+
+ LRESULT OnPaint(UINT /*uMsg*/,
+ WPARAM /*wParam*/,
+ LPARAM /*lParam*/,
+ BOOL& bHandled) {
+ static float previous_position = -1.0f;
+
+ float position = media::Movie::get()->GetPosition();
+ if (static_cast<int>(position * 10) !=
+ static_cast<int>(previous_position * 10)) {
+ previous_position = position;
+ wchar_t szBuff[200];
+ float duration = media::Movie::get()->GetDuration();
+ float fps = 29.97f;
+ wsprintf(szBuff, L"%i.%i / %i.%i, %i / %i",
+ static_cast<int>(position),
+ static_cast<int>(position * 10) % 10,
+ static_cast<int>(duration),
+ static_cast<int>(duration * 10) % 10,
+ static_cast<int>(position * fps),
+ static_cast<int>(duration * fps));
+ SetDlgItemText(IDC_SEEKLOCATION, szBuff);
+ bHandled = TRUE;
+ return FALSE;
+ }
+ bHandled = FALSE;
+ return FALSE;
+ }
+
+ virtual BOOL OnIdle() {
+ wchar_t szBuff[200];
+ float position = media::Movie::get()->GetPosition();
+ float duration = media::Movie::get()->GetDuration();
+ // TODO(fbarchard): Use frame rate property when it exists.
+ float fps = 29.97f;
+ wsprintf(szBuff, L"%i.%i / %i.%i, %i / %i",
+ static_cast<int>(position),
+ static_cast<int>(position * 10) % 10,
+ static_cast<int>(duration),
+ static_cast<int>(duration * 10) % 10,
+ static_cast<int>(position * fps),
+ static_cast<int>(duration * fps));
+ SetDlgItemText(IDC_SEEKLOCATION, szBuff);
+ return FALSE;
+ }
+
+ LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/,
+ BOOL& /*bHandled*/) {
+ CMessageLoop* pLoop = g_module.GetMessageLoop();
+ ATLASSERT(pLoop != NULL);
+ pLoop->AddMessageFilter(this);
+ pLoop->AddIdleHandler(this);
+ return TRUE;
+ }
+
+ LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/,
+ BOOL& bHandled) {
+ // unregister message filtering and idle updates
+ CMessageLoop* pLoop = g_module.GetMessageLoop();
+ ATLASSERT(pLoop != NULL);
+ pLoop->RemoveMessageFilter(this);
+ pLoop->RemoveIdleHandler(this);
+ bHandled = FALSE;
+ return 1;
+ }
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_SEEK_H_
diff --git a/media/tools/player_wtl/toolbar.bmp b/media/tools/player_wtl/toolbar.bmp
new file mode 100644
index 0000000..5843d36
--- /dev/null
+++ b/media/tools/player_wtl/toolbar.bmp
Binary files differ
diff --git a/media/tools/player_wtl/view.h b/media/tools/player_wtl/view.h
new file mode 100644
index 0000000..ce55c10
--- /dev/null
+++ b/media/tools/player_wtl/view.h
@@ -0,0 +1,420 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_VIEW_H_
+#define MEDIA_TOOLS_PLAYER_WTL_VIEW_H_
+
+#include <stdio.h>
+#include <process.h>
+#include <string.h>
+
+#include "media/base/buffers.h"
+#include "media/base/yuv_convert.h"
+#include "media/tools/player_wtl/movie.h"
+#include "media/tools/player_wtl/player_wtl.h"
+#include "media/tools/player_wtl/wtl_renderer.h"
+
+// Fetchs current time as milliseconds.
+// Returns as double for high duration and precision.
+inline double GetTime() {
+ LARGE_INTEGER perf_time, perf_hz;
+ QueryPerformanceFrequency(&perf_hz); // May change with speed step.
+ QueryPerformanceCounter(&perf_time);
+ return perf_time.QuadPart * 1000.0 / perf_hz.QuadPart; // Convert to ms.
+}
+
+// Paints the current movie frame (with scaling) to the display.
+// TODO(fbarchard): Consider rewriting as view.cc and view.h
+class WtlVideoWindow : public CScrollWindowImpl<WtlVideoWindow> {
+ public:
+ DECLARE_WND_CLASS_EX(NULL, 0, -1)
+
+ BEGIN_MSG_MAP(WtlVideoWindow)
+ MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
+ CHAIN_MSG_MAP(CScrollWindowImpl<WtlVideoWindow>);
+ END_MSG_MAP()
+
+ WtlVideoWindow() {
+ size_.cx = 0;
+ size_.cy = 0;
+ view_size_ = 2; // Normal size.
+ view_rotate_ = media::ROTATE_0;
+ renderer_ = new WtlVideoRenderer(this);
+ last_frame_ = NULL;
+ hbmp_ = NULL;
+ }
+
+ BOOL PreTranslateMessage(MSG* /*msg*/) {
+ return FALSE;
+ }
+
+ void AllocateVideoBitmap(CDCHandle dc) {
+ // See note on SetSize for why we check size_.cy.
+ if (bmp_.IsNull() && size_.cy > 0) {
+ BITMAPINFO bmi;
+ bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
+ bmi.bmiHeader.biWidth = size_.cx;
+ bmi.bmiHeader.biHeight = size_.cy;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = 0;
+ bmi.bmiHeader.biXPelsPerMeter = 100;
+ bmi.bmiHeader.biYPelsPerMeter = 100;
+ bmi.bmiHeader.biClrUsed = 0;
+ bmi.bmiHeader.biClrImportant = 0;
+ void* pBits;
+ bmp_.CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);
+ SetScrollOffset(0, 0, FALSE);
+ SetScrollSize(size_);
+ }
+ }
+
+ // Called on the video renderer's thread.
+ // Note that AllocateVideoBitmap examines the size_.cy value to determine
+ // if a bitmap should be allocated, so we set it last to avoid a race
+ // condition.
+ void SetSize(int cx, int cy) {
+ size_.cx = cx;
+ size_.cy = cy;
+ }
+
+ void Reset() {
+ if (!bmp_.IsNull()) {
+ bmp_.DeleteObject();
+ }
+ size_.cx = 0;
+ size_.cy = 0;
+ // TODO(frank): get rid of renderer at reset too.
+ }
+
+ LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/,
+ BOOL& /*bHandled*/) {
+ CDCHandle dc = reinterpret_cast<HDC>(wParam);
+ AllocateVideoBitmap(dc);
+ RECT rect;
+ GetClientRect(&rect);
+ int x = 0;
+ int y = 0;
+ if (!bmp_.IsNull()) {
+ x = size_.cx + 1;
+ y = size_.cy + 1;
+ }
+ if (rect.right > m_sizeAll.cx) {
+ RECT rectRight = rect;
+ rectRight.left = x;
+ rectRight.bottom = y;
+ dc.FillRect(&rectRight, COLOR_WINDOW);
+ }
+ if (rect.bottom > m_sizeAll.cy) {
+ RECT rectBottom = rect;
+ rectBottom.top = y;
+ dc.FillRect(&rectBottom, COLOR_WINDOW);
+ }
+ if (!bmp_.IsNull()) {
+ dc.MoveTo(size_.cx, 0);
+ dc.LineTo(size_.cx, size_.cy);
+ dc.LineTo(0, size_.cy);
+ }
+ return 0;
+ }
+
+ // Convert the video frame to RGB and Blit.
+ void ConvertFrame(media::VideoFrame * video_frame) {
+ media::VideoSurface frame_in;
+ bool lock_result = video_frame->Lock(&frame_in);
+ DCHECK(lock_result);
+ BITMAP bm;
+ bmp_.GetBitmap(&bm);
+ int dibwidth = bm.bmWidth;
+ int dibheight = bm.bmHeight;
+
+ uint8 *movie_dib_bits = reinterpret_cast<uint8 *>(bm.bmBits) +
+ bm.bmWidthBytes * (bm.bmHeight - 1);
+ int dibrowbytes = -bm.bmWidthBytes;
+ int clipped_width = frame_in.width;
+ if (dibwidth < clipped_width) {
+ clipped_width = dibwidth;
+ }
+ int clipped_height = frame_in.height;
+ if (dibheight < clipped_height) {
+ clipped_height = dibheight;
+ }
+
+ int scaled_width = clipped_width;
+ int scaled_height = clipped_height;
+ switch (view_size_) {
+ case 0:
+ scaled_width = clipped_width / 4;
+ scaled_height = clipped_height / 4;
+ break;
+
+ case 1:
+ scaled_width = clipped_width / 2;
+ scaled_height = clipped_height / 2;
+ break;
+
+ case 2:
+ default: // Assume 1:1 for stray view sizes.
+ scaled_width = clipped_width;
+ scaled_height = clipped_height;
+ break;
+
+ case 3: // Double.
+ scaled_width = clipped_width;
+ scaled_height = clipped_height;
+ clipped_width = scaled_width / 2;
+ clipped_height = scaled_height / 2;
+ break;
+
+ case 4: // Triple.
+ scaled_width = clipped_width;
+ scaled_height = clipped_height;
+ clipped_width = scaled_width / 3;
+ clipped_height = scaled_height / 3;
+ break;
+
+ case 5: // Quadruple.
+ scaled_width = clipped_width;
+ scaled_height = clipped_height;
+ clipped_width = scaled_width / 4;
+ clipped_height = scaled_height / 4;
+ break;
+ }
+
+ // Append each frame to end of file.
+ bool enable_dump_yuv_file = media::Movie::get()->GetDumpYuvFileEnable();
+ if (enable_dump_yuv_file) {
+ DumpYUV(frame_in);
+ }
+
+#ifdef TESTING
+ double yuv_time_start = GetTime(); // Start timer.
+#endif
+
+ bool enable_draw = media::Movie::get()->GetDrawEnable();
+ if (enable_draw) {
+ DCHECK(bm.bmBitsPixel == 32);
+ DrawYUV(frame_in,
+ movie_dib_bits,
+ dibrowbytes,
+ clipped_width,
+ clipped_height,
+ scaled_width,
+ scaled_height);
+ }
+#ifdef TESTING
+ double yuv_time_end = GetTime();
+ static int yuv_time_count = 0;
+ static double yuv_time_sum = 0.;
+ if (!yuv_time_count)
+ yuv_time_sum = 0.;
+ yuv_time_sum += (yuv_time_end - yuv_time_start);
+ ++yuv_time_count;
+
+ char outputbuf[512];
+ _snprintf_s(outputbuf, sizeof(outputbuf), "test %f", yuv_time_end);
+ _snprintf_s(outputbuf, sizeof(outputbuf),
+ "yuv %5.2f ms avg %5.2f ms\n",
+ yuv_time_end - yuv_time_start,
+ yuv_time_sum / yuv_time_count);
+ OutputDebugStringA(outputbuf);
+#endif
+ }
+
+ void DoPaint(CDCHandle dc) {
+ AllocateVideoBitmap(dc);
+ if (!bmp_.IsNull()) {
+ scoped_refptr<media::VideoFrame> frame;
+ renderer_->GetCurrentFrame(&frame);
+ if (frame.get()) {
+ base::TimeDelta frame_timestamp = frame->GetTimestamp();
+ if (frame != last_frame_ || frame_timestamp != last_timestamp_) {
+ last_frame_ = frame;
+ last_timestamp_ = frame_timestamp;
+ ConvertFrame(frame);
+ }
+ frame = NULL;
+ }
+
+#ifdef TESTING
+ double paint_time_start = GetTime();
+ static double paint_time_previous = 0;
+ if (!paint_time_previous)
+ paint_time_previous = paint_time_start;
+#endif
+ CDC dcMem;
+ dcMem.CreateCompatibleDC(dc);
+ HBITMAP hBmpOld = hbmp_ ? hbmp_: dcMem.SelectBitmap(bmp_);
+ dc.BitBlt(0, 0, size_.cx, size_.cy, dcMem, 0, 0, SRCCOPY);
+ dcMem.SelectBitmap(hBmpOld);
+#ifdef TESTING
+ double paint_time_end = GetTime();
+ static int paint_count = 0;
+ static double paint_time_sum = 0;
+ paint_time_sum += paint_time_end - paint_time_start;
+ ++paint_count;
+ char outputbuf[512];
+ _snprintf_s(outputbuf, sizeof(outputbuf),
+ "paint time %5.2f ms blit %5.2f ms avg %5.2f ms\n",
+ paint_time_start - paint_time_previous,
+ paint_time_end - paint_time_start,
+ paint_time_sum / paint_count);
+ OutputDebugStringA(outputbuf);
+
+ paint_time_previous = paint_time_start;
+#endif
+ }
+ } // End of DoPaint function.
+
+ void SetViewSize(int view_size) {
+ view_size_ = view_size;
+ }
+
+ int GetViewSize() {
+ return view_size_;
+ }
+
+ void SetViewRotate(int view_rotate) {
+ switch (view_rotate) {
+ default:
+ case 0:
+ view_rotate_ = media::ROTATE_0;
+ break;
+ case 1:
+ view_rotate_ = media::ROTATE_90;
+ break;
+ case 2:
+ view_rotate_ = media::ROTATE_180;
+ break;
+ case 3:
+ view_rotate_ = media::ROTATE_270;
+ break;
+ case 4:
+ view_rotate_ = media::MIRROR_ROTATE_0;
+ break;
+ case 5:
+ view_rotate_ = media::MIRROR_ROTATE_180;
+ break;
+ }
+ }
+
+ int GetViewRotate() {
+ int view_rotate = 0;
+ switch (view_rotate_) {
+ default:
+ case media::ROTATE_0:
+ view_rotate = 0;
+ break;
+ case media::ROTATE_90:
+ view_rotate = 1;
+ break;
+ case media::ROTATE_180:
+ view_rotate = 2;
+ break;
+ case media::ROTATE_270:
+ view_rotate = 3;
+ break;
+ case media::MIRROR_ROTATE_0:
+ view_rotate = 4;
+ break;
+ case media::MIRROR_ROTATE_180:
+ view_rotate = 5;
+ break;
+ }
+ return view_rotate;
+ }
+
+ void SetBitmap(HBITMAP hbmp) {
+ hbmp_ = hbmp;
+ }
+
+ CBitmap bmp_; // Used by mainfrm.h.
+ SIZE size_; // Used by WtlVideoWindow.
+ scoped_refptr<WtlVideoRenderer> renderer_; // Used by WtlVideoWindow.
+
+ private:
+ HBITMAP hbmp_; // For Images
+ // View Size: 0=1/4, 1=0.5, 2=normal, 3=2x, 4=3x, 5=4x, 3=fit, 4=full.
+ int view_size_;
+
+ // View Rotate 0-5 for ID_VIEW_ROTATE0 to ID_VIEW_MIRROR_VERTICAL
+ media::Rotate view_rotate_;
+
+ // Draw a frame of YUV to an RGB buffer with scaling.
+ // Handles different YUV formats.
+ void DrawYUV(const media::VideoSurface &frame_in,
+ uint8 *movie_dib_bits,
+ int dibrowbytes,
+ int clipped_width,
+ int clipped_height,
+ int scaled_width,
+ int scaled_height) {
+ media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ?
+ media::YV12 : media::YV16;
+
+ // Simple convert is not necessary for performance, but allows
+ // easier alternative implementations.
+ if ((view_rotate_ == media::ROTATE_0) && // Not scaled or rotated
+ (view_size_ == 2)) {
+ media::ConvertYUVToRGB32(frame_in.data[0],
+ frame_in.data[1],
+ frame_in.data[2],
+ movie_dib_bits,
+ scaled_width, scaled_height,
+ frame_in.strides[0],
+ frame_in.strides[1],
+ dibrowbytes,
+ yuv_type);
+ } else {
+ media::ScaleYUVToRGB32(frame_in.data[0],
+ frame_in.data[1],
+ frame_in.data[2],
+ movie_dib_bits,
+ clipped_width, clipped_height,
+ scaled_width, scaled_height,
+ frame_in.strides[0],
+ frame_in.strides[1],
+ dibrowbytes,
+ yuv_type,
+ view_rotate_);
+ }
+ }
+
+ // Diagnostic function to write out YUV in format compatible with PYUV tool.
+ void DumpYUV(const media::VideoSurface &frame_in) {
+ FILE * file_yuv = fopen("raw.yuv", "ab+"); // Open for append binary.
+ if (file_yuv != NULL) {
+ fseek(file_yuv, 0, SEEK_END);
+ const size_t frame_size = frame_in.width * frame_in.height;
+ for (size_t y = 0; y < frame_in.height; ++y)
+ fwrite(frame_in.data[0]+frame_in.strides[0]*y,
+ frame_in.width, sizeof(uint8), file_yuv);
+ for (size_t y = 0; y < frame_in.height/2; ++y)
+ fwrite(frame_in.data[1]+frame_in.strides[1]*y,
+ frame_in.width/2, sizeof(uint8), file_yuv);
+ for (size_t y = 0; y < frame_in.height/2; ++y)
+ fwrite(frame_in.data[2]+frame_in.strides[2]*y,
+ frame_in.width/2, sizeof(uint8), file_yuv);
+ fclose(file_yuv);
+
+#if TESTING
+ static int frame_dump_count = 0;
+ char outputbuf[512];
+ _snprintf_s(outputbuf, sizeof(outputbuf), "yuvdump %4d %dx%d stride %d\n",
+ frame_dump_count, frame_in.width, frame_in.height,
+ frame_in.strides[0]);
+ OutputDebugStringA(outputbuf);
+ ++frame_dump_count;
+#endif
+ }
+ }
+
+ media::VideoFrame* last_frame_;
+ base::TimeDelta last_timestamp_;
+
+ DISALLOW_COPY_AND_ASSIGN(WtlVideoWindow);
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_VIEW_H_
diff --git a/media/tools/player_wtl/wtl_renderer.cc b/media/tools/player_wtl/wtl_renderer.cc
new file mode 100644
index 0000000..8a850f7
--- /dev/null
+++ b/media/tools/player_wtl/wtl_renderer.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/tools/player_wtl/wtl_renderer.h"
+
+#include "media/tools/player_wtl/view.h"
+
+WtlVideoRenderer::WtlVideoRenderer(WtlVideoWindow* window)
+ : window_(window) {
+}
+
+WtlVideoRenderer::~WtlVideoRenderer() {
+}
+
+// static
+bool WtlVideoRenderer::IsMediaFormatSupported(
+ const media::MediaFormat& media_format) {
+ int width = 0;
+ int height = 0;
+ return ParseMediaFormat(media_format, &width, &height);
+}
+
+void WtlVideoRenderer::OnStop() {
+}
+
+bool WtlVideoRenderer::OnInitialize(media::VideoDecoder* decoder) {
+ int width = 0;
+ int height = 0;
+ if (!ParseMediaFormat(decoder->media_format(), &width, &height))
+ return false;
+ window_->SetSize(width, height);
+ return true;
+}
+
+void WtlVideoRenderer::OnFrameAvailable() {
+ window_->Invalidate();
+}
diff --git a/media/tools/player_wtl/wtl_renderer.h b/media/tools/player_wtl/wtl_renderer.h
new file mode 100644
index 0000000..86aa61f
--- /dev/null
+++ b/media/tools/player_wtl/wtl_renderer.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+// Video renderer for media player.
+
+#ifndef MEDIA_TOOLS_PLAYER_WTL_WTL_RENDERER_H_
+#define MEDIA_TOOLS_PLAYER_WTL_WTL_RENDERER_H_
+
+#include "media/filters/video_renderer_base.h"
+
+class WtlVideoWindow;
+
+class WtlVideoRenderer : public media::VideoRendererBase {
+ public:
+ explicit WtlVideoRenderer(WtlVideoWindow* window);
+
+ static bool IsMediaFormatSupported(const media::MediaFormat& media_format);
+
+ protected:
+ // VideoRendererBase implementation.
+ virtual bool OnInitialize(media::VideoDecoder* decoder);
+ virtual void OnStop();
+ virtual void OnFrameAvailable();
+
+ private:
+ // Only allow to be deleted by reference counting.
+ friend class scoped_refptr<WtlVideoRenderer>;
+ virtual ~WtlVideoRenderer();
+
+ WtlVideoWindow* window_;
+
+ DISALLOW_COPY_AND_ASSIGN(WtlVideoRenderer);
+};
+
+#endif // MEDIA_TOOLS_PLAYER_WTL_WTL_RENDERER_H_