diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 18:43:53 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 18:43:53 +0000 |
commit | 6e7c24ee5cd7ce88266ceae158c31c62d7498d3f (patch) | |
tree | 7fe0d691192959f1a31095aa35dc5efb147f88c8 /media/tools/player_wtl | |
parent | a999b0e58e1ca80435c7322df5cb229b64be113f (diff) | |
download | chromium_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.h | 127 | ||||
-rw-r--r-- | media/tools/player_wtl/mainfrm.h | 718 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.cc | 172 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.h | 98 | ||||
-rw-r--r-- | media/tools/player_wtl/player_wtl.cc | 93 | ||||
-rw-r--r-- | media/tools/player_wtl/player_wtl.h | 28 | ||||
-rw-r--r-- | media/tools/player_wtl/player_wtl.ico | bin | 0 -> 1078 bytes | |||
-rw-r--r-- | media/tools/player_wtl/player_wtl.rc | 544 | ||||
-rw-r--r-- | media/tools/player_wtl/props.h | 325 | ||||
-rw-r--r-- | media/tools/player_wtl/resource.h | 78 | ||||
-rw-r--r-- | media/tools/player_wtl/seek.h | 97 | ||||
-rw-r--r-- | media/tools/player_wtl/toolbar.bmp | bin | 0 -> 1438 bytes | |||
-rw-r--r-- | media/tools/player_wtl/view.h | 420 | ||||
-rw-r--r-- | media/tools/player_wtl/wtl_renderer.cc | 38 | ||||
-rw-r--r-- | media/tools/player_wtl/wtl_renderer.h | 36 |
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 Binary files differnew file mode 100644 index 0000000..93d8182 --- /dev/null +++ b/media/tools/player_wtl/player_wtl.ico 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 Binary files differnew file mode 100644 index 0000000..5843d36 --- /dev/null +++ b/media/tools/player_wtl/toolbar.bmp 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_ |