home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2004 March / PCWELT_3_2004.ISO / pcwsoft / flaskmpeg_078_39_src.z.exe / flaskmpeg / Player.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  19.8 KB  |  655 lines

  1. /* 
  2.  *  Player.cpp 
  3.  *
  4.  *    Copyright (C) Alberto Vigata - July 2000 - ultraflask@yahoo.com
  5.  *
  6.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  7.  *    
  8.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  FlasKMPEG is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23.  
  24.  
  25.  
  26. #include "FlasKMPEG.h"
  27. #include "auxiliary.h"
  28. #include "resource.h"
  29. #include "Player.h"
  30. #include "debug.h"
  31. #include "AudioProperties.h"
  32. #include "PlayerThread.h"
  33. #include "OutputPad.h"
  34. #include "./Misc/StatsStrings.h"
  35. #include "./Video/VideoWrapper.h"
  36. #include "./RunState.h"
  37. #include "flppreceiver.h"
  38. #include <string>
  39.  
  40. // Extern globals
  41. extern TRunState        rs;
  42. extern HINSTANCE        hInst;
  43.  
  44. extern HWND                hMainWnd;
  45. extern BITMAPINFO        DibInfo;
  46. extern BOOL             playerStopped; //Needed for main window to redraw
  47.                                                           //   FlasKMPEG logo.
  48.  
  49. // Local variables
  50. static HWND                 hPlayerDlg;
  51.  
  52. static CRITICAL_SECTION     GlobalCriticalSection; 
  53. static bool                 SeekInProgress;
  54. static i64                     diferencia;
  55. static TStatsStrings        stats;      //This is a big one
  56. DWORD play_start_time;
  57. unsigned play_frame_count;
  58.  
  59.  
  60. // This is the profile we will work on in 
  61. // the control
  62. // initialized on ShowPlayer()
  63. TProfile pprof;
  64. static TPPost pps;      // we store locally the current post processing settings
  65.  
  66.  
  67. const int nTrackBarRange = 1000;
  68.  
  69. void ShowPlayer( TProfile *prof )
  70. {
  71.  
  72.   // Don't start player if bad post processing parameters
  73.   pprof = *prof;
  74.   TPPost pp;
  75.   FromConfigToPPost(&pprof, &pp, 
  76.                      rs.video->GetWidth(), 
  77.                      rs.video->GetHeight(),
  78.                      rs.video->DAR,
  79.                      FRAME_YV12 );
  80.  
  81.  
  82.   if( CheckVideoParameters( &pp ) ) {
  83.     if(!rs.hPlayerWnd)
  84.     {
  85.       rs.hPlayerWnd = CreateDialog(hInst,MAKEINTRESOURCE(IDD_PLAYER), hMainWnd, (DLGPROC) PlayerDlg);
  86.       ShowWindow(rs.hPlayerWnd, SW_SHOW);
  87.     }  
  88.   }
  89. }
  90.  
  91. static CFlEvent evPlayerEnded;
  92.  
  93. TProfile *GetCurrentPlayerSettings()
  94. {
  95.   FromPPostToConfig( &pprof, &pps );
  96.   return &pprof;
  97. }
  98.  
  99. TProfile *HidePlayer()
  100. {
  101.   TProfile *prof = NULL;
  102.   if(rs.hPlayerWnd)
  103.   {
  104.     prof = &pprof;
  105.     evPlayerEnded.Reset();
  106.     SendMessage( rs.hPlayerWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0);
  107.     evPlayerEnded.Wait();
  108.     DestroyWindow(rs.hPlayerWnd);
  109.     rs.hPlayerWnd = NULL;
  110.   }
  111.   return prof;
  112. }
  113.  
  114. void Localize(HWND hDlg)
  115. {
  116.     DlgSetText(hDlg, R_PLAYER_PLAY_BUTTON,             GS(R_PLAYER_PLAY_BUTTON) );
  117.     DlgSetText(hDlg, R_PLAYER_STOP_BUTTON,             GS(R_PLAYER_STOP_BUTTON) );
  118.     DlgSetText(hDlg, R_PLAYER_VIDEOSTATS_BOX,          GS(R_PLAYER_VIDEOSTATS_BOX) );
  119.     DlgSetText(hDlg, R_PLAYER_FILETIME_TITLE,          GS(R_PLAYER_FILETIME_TITLE) );
  120.     DlgSetText(hDlg, R_PLAYER_FILE_TITLE,              GS(R_PLAYER_FILE_TITLE) );
  121.     DlgSetText(hDlg, R_PLAYER_VIDEOSIZE_TITLE,         GS(R_PLAYER_VIDEOSIZE_TITLE) );
  122.     DlgSetText(hDlg, R_PLAYER_FPS_TITLE,               GS(R_PLAYER_FPS_TITLE) );
  123.     DlgSetText(hDlg, R_PLAYER_TOTALFILESIZE_TITLE,     GS(R_PLAYER_TOTALFILESIZE_TITLE) );
  124.     DlgSetText(hDlg, R_PLAYER_ASPECTRATIO_TITLE,       GS(R_PLAYER_ASPECTRATIO_TITLE) );
  125.     DlgSetText(hDlg, R_PLAYER_BITRATE_TITLE,           GS(R_PLAYER_BITRATE_TITLE) );
  126.     DlgSetText(hDlg, R_PLAYER_VIDEOSTRUCTURE_TITLE,    GS(R_PLAYER_VIDEOSTRUCTURE_TITLE) );
  127.     DlgSetText(hDlg, R_PLAYER_SEEKFIRST_BUTTON,        GS(R_PLAYER_SEEKFIRST_BUTTON) );
  128.     DlgSetText(hDlg, R_PLAYER_DETECTEDFPS_TITLE,       GS(R_PLAYER_DETECTEDFPS_TITLE) );
  129.     DlgSetText(hDlg, R_PLAYER_VIDEOFORMAT_TITLE,       GS(R_PLAYER_VIDEOFORMAT_TITLE) );
  130.  
  131.     return;
  132. }
  133.  
  134.  
  135.  
  136. #define OUTPUT_POPUP_BASE 10000
  137. static void ShowOutputPopup(HWND hDlg, HWND hButton)
  138. {
  139.   HMENU hPopup = CreatePopupMenu();
  140.   for(int i=0; i<rs.plugs.OutPluginCount; i++)
  141.   {
  142.     MenuAddItem( hPopup, i, OUTPUT_POPUP_BASE+i, rs.plugs.outPlugs[i].ID );
  143.   }
  144.   CheckMenuItem(hPopup,rs.selected_out_plug, MF_BYPOSITION|MF_CHECKED);
  145.   MenuAddSeparator(hPopup, i);
  146.   MenuAddItem(hPopup, i+1, OUTPUT_POPUP_BASE+i+1, "Configure Output Module");
  147.  
  148.   // Get the rect of the button
  149.   RECT rcButton;
  150.   GetWindowRect(hButton, &rcButton);
  151.   // Now show the popup
  152.   TrackPopupMenu( hPopup, 
  153.                   TPM_LEFTALIGN|TPM_TOPALIGN|TPM_LEFTBUTTON,
  154.                   rcButton.right, rcButton.top,
  155.                   0, hDlg, NULL);
  156.   // thats it
  157. }
  158.  
  159. void CreateDefaultJob()
  160. {
  161.   // If there are no jobs create one
  162.   if(!rs.vBatchList.size())
  163.   {
  164.     CFrame *pDummyFrame;
  165.     
  166.     TBatchListElement el;
  167.     // Calculate start position
  168.     // Go to the beginning
  169.     rs.video->SetStreamPos(0);
  170.     // Decode the first frame available
  171.     TVideoOptions sStartOpt;
  172.     memset( &sStartOpt, 0, sizeof(TVideoOptions));
  173.     sStartOpt.bStartInSync = false;
  174.     sStartOpt.idctIndex    = rs.conf.idctIndex;
  175.     sStartOpt.pFrameBuffer = NULL;
  176.     
  177.     rs.video->Start(&sStartOpt);
  178.     rs.video->GetNextFrame(&pDummyFrame);
  179.     rs.video->Stop();
  180.     
  181.     el.nStart = rs.video->GetLastDecodedFrameStart();
  182.     el.nEnd   = rs.video->GetStreamSize();
  183.     rs.vBatchList.push_back(el);
  184.   }  
  185. }
  186.  
  187. static void DeInitializePlayer(HWND hDlg, CPlayerThread * &pPlayer, 
  188.                                CAudioThread * &pAudioPlayer,
  189.                                CMasterClock * &pMasterClock )
  190. {
  191.  
  192.   if( !pMasterClock || !pAudioPlayer || !pPlayer )
  193.     return;
  194.  
  195.   // Stop playing thread
  196.   pPlayer->Exit();
  197.   pPlayer=NULL;
  198.   
  199.   // Create default job
  200.   CreateDefaultJob();
  201.   
  202.   KillTimer( hDlg, 2);
  203.   // SetWindowSize();
  204.   // InvalidateRect(hMainWnd, NULL, true);
  205.  
  206.   // Stop the audio thread
  207.   pAudioPlayer->Exit();
  208.   delete pAudioPlayer;
  209.   pAudioPlayer = NULL;
  210.  
  211.   // Delete de master clock
  212.   delete pMasterClock;
  213.   pMasterClock = NULL;
  214.  
  215.   // Set end dialog event to wake anyone waiting on HidePlayer
  216.   evPlayerEnded.Set();
  217.   
  218.   
  219. }
  220.  
  221. void RenderBatchList( HWND hList )
  222. {
  223.   int i, nSize = rs.vBatchList.size();
  224.   char str[256];
  225.  
  226.   SendMessage(hList, LB_RESETCONTENT, 0, 0);
  227.   for(i=0; i<nSize; i++)
  228.   {
  229.     int nJobSize = (rs.vBatchList[i].nEnd - rs.vBatchList[i].nStart)>>20;
  230.     sprintf( str, "Job %d. size %d MB.", i+1, nJobSize );
  231.     SendMessage(hList, LB_ADDSTRING, 0, (WPARAM)str);
  232.   }
  233. }
  234.  
  235. void RenderTrackbarSel( HWND hTrackbar , TBatchListElement *pItem )
  236. {
  237.   LONG start = (LONG)(((double)pItem->nStart/(double)rs.video->GetStreamSize()) * (double)nTrackBarRange);
  238.   LONG end   = (LONG)(((double)pItem->nEnd  /(double)rs.video->GetStreamSize()) * (double)nTrackBarRange);
  239.  
  240.   SendMessage( hTrackbar, TBM_SETSEL, (WPARAM)(BOOL)true, (LPARAM)MAKELONG(start, end) );
  241. }
  242.  
  243. void SetupTooltips(HWND hDlg)
  244. {
  245.   HINSTANCE hInst = rs.hInst;
  246.  
  247. #define ATTACH(id, title, text){ DlgAttachToolTip( hInst, hDlg, id, title, text); }
  248.  
  249.  
  250.   // Play controls
  251.   ATTACH( IDC_SEEKFIRST, "Seek Beginning", "Sets cursor at the \n\rbeginning." )
  252.   ATTACH( IDC_PLAYBACK, "Play Backwards", "Plays video backwards." )
  253.   ATTACH( IDC_PLAY, "Play", "Plays video." )
  254.   ATTACH( IDC_STOP, "Stop", "Stops current action." )
  255.   ATTACH( IDC_PREVFRAME, "Previous Frame", "Displays previous frame." )
  256.   ATTACH( IDC_NEXTFRAME, "Next Frame", "Displays next frame." )
  257.   ATTACH( IDC_FASTBACK, "Fast Rewind", "Rewinds video backwards." )
  258.   ATTACH( IDC_FASTFOR, "Fast Forward", "Fast forwards video." )
  259.   ATTACH( IDC_SEEKEND, "Seek End", "Goes to the end of \n\r the video." )
  260.  
  261.   // Selection Controls
  262.   ATTACH( IDC_STARTMARKER, "Start Marker", "Start of selection" )  
  263.   ATTACH( IDC_ENDMARKER, "End Marker", "End of selection" )  
  264.   ATTACH( IDC_GOSTARTMARKER, "Jump Start Marker", "Jumps to wherever\n\r the start marker is \n\rplaced." )  
  265.   ATTACH( IDC_GOENDMARKER, "Jump End Marker", "Jumps to wherever\n\r the end marker is \n\rplaced." )  
  266.   
  267.   ATTACH( IDC_LIST, "Job List", "List of jobs\n\r currently created." )  
  268.  
  269.  
  270. #undef ATTACH
  271. }
  272.  
  273.  
  274. // Define an the report class for our dialog
  275. // The class will send the WM_NEWFRAMEINFO message
  276. // to the dialog every time there is new info about
  277. // a frame
  278. #define WM_NEWPPSETTINGS  WM_USER + 1
  279.  
  280. class CPlayerListener: public FlPPReceiver
  281. {
  282. public:
  283.   CPlayerListener(HWND hDlg)
  284.   {
  285.     m_hDlg = hDlg;
  286.   }
  287.   
  288.   int PutPPSettings( TPPost *pp )
  289.   {
  290.     if(m_hDlg)
  291.       PostMessage(m_hDlg, WM_NEWPPSETTINGS, (WPARAM)pp, (LPARAM)0);
  292.     
  293.     return 0;
  294.   }
  295.   void SetDlg( HWND hDlg ){ m_hDlg = hDlg; }
  296.   
  297. private:
  298.   HWND m_hDlg;
  299.   
  300. };
  301.  
  302.  
  303. LRESULT CALLBACK PlayerDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  304. {
  305.     static HANDLE hPlayer;
  306.   i64 nFilePos;
  307.   int nSel;
  308.     static int playerTimer;
  309.     int fPosition, lPosition;
  310.     static bool userIsTracking;
  311.     char szTemp[1024];
  312.   static CPlayerThread *pPlayer;
  313.   static CAudioThread  *pAudioPlayer;
  314.   static CMasterClock  *pMasterClock;
  315.   static COutputPadDlg  vidPanel(hMainWnd, hDlg, hInst);
  316.   static TBatchListElement trackBarSpan;
  317.   CPlayerThread::playerStates nState;
  318.   static CPlayerListener listener(hDlg);
  319.   static FlPostProcess pp; 
  320.   static TStatsStrings stats;
  321.   string title;
  322.  
  323.  
  324.     switch (message)
  325.     {
  326.         case WM_TIMER:
  327.             // Total frames
  328.             // Total file size
  329.             sprintf( szTemp, "%d Mbytes", (unsigned)(rs.video->GetStreamSize() >> 20));
  330.             SetDlgItemText(hDlg, IDC_FILESIZE, szTemp);
  331.             // Video size
  332.             DlgSetText(hDlg,IDC_VIDEOSIZE ,stats.InMedia.video_size);
  333.             // Frame rate
  334.             DlgSetText(hDlg,IDC_FRAMERATE ,stats.InMedia.video_frame_rate);
  335.             //Detected FPS
  336.             DlgSetText(hDlg,IDC_DETECTEDFPS ,stats.InMedia.video_detected_frame_rate);
  337.             // Aspect Ratio
  338.             DlgSetText(hDlg,IDC_ASPECTRATIO ,stats.InMedia.video_aspect_ratio_information);
  339.             // Bitrate
  340.             DlgSetText(hDlg,IDC_BITRATE ,stats.InMedia.video_bit_rate);
  341.             // Progressive sequence
  342.             DlgSetText(hDlg,IDC_PROGRESSIVE ,stats.InMedia.video_structure);
  343.             //DlgSetText(hDlg,IDC_PROGRESSIVE ,video->internalPTS/27000.0);
  344.             //DlgSetText(hDlg,IDC_BITRATE ,diferencia);
  345.  
  346.       nState = pPlayer->GetState();
  347.             fPosition=true;
  348.             lPosition= (int)(((double)(i64)(rs.video->GetStreamPos())/(double)(i64)(rs.video->GetStreamSize()))*nTrackBarRange);
  349.             if( !userIsTracking && 
  350.           nState!=CPlayerThread::stNextFrame  &&
  351.           nState!=CPlayerThread::stPrevFrame )
  352.                 SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_SETPOS, (WPARAM) (BOOL) fPosition,(LPARAM) (LONG) lPosition); 
  353.  
  354.             break;
  355.         case WM_INITDIALOG:
  356.             RenderStatsStrings(&stats);
  357.  
  358.       title ="Control Panel - ";
  359.       title += rs.video->GetFileName();
  360.       SetText( hDlg, (char *)title.c_str() ); 
  361.  
  362.       vidPanel.SetWindows( hMainWnd, hDlg );
  363.  
  364.       SetWindowLong( hDlg, GWL_EXSTYLE, WS_EX_TOOLWINDOW );
  365.       
  366.       SetupTooltips( hDlg );
  367.  
  368.       Localize(hDlg);
  369.  
  370.       // put the audio in place
  371.       rs.video->SetStreamPos(rs.startFilePos);
  372.             if(rs.audio)
  373.                 rs.audio->SetStreamPos(rs.startFilePos);
  374.     
  375.  
  376.             // Get post processing options from config
  377.       FromConfigToPPost(&pprof, &pps, 
  378.                          rs.video->GetWidth(), 
  379.                          rs.video->GetHeight(),
  380.                          rs.video->DAR,
  381.                          FRAME_YV12 );
  382.  
  383.       
  384.       if( !pp.Set( &pps ) ) {
  385.         DBG_STR((str, "Player - Settings in profile are not valid\n"))
  386.         return FALSE;
  387.       }
  388.  
  389.             WindowClientResize( hMainWnd, pp.GetWidth() , pp.GetHeight() );
  390.  
  391.       // Create Master Clock
  392.       pMasterClock = new CMasterClock(ClkSystem);
  393.       if( !pMasterClock->Initialize() )
  394.       {
  395.         delete pMasterClock;
  396.         pMasterClock = NULL;
  397.       }
  398.  
  399.  
  400.  
  401.       hPlayerDlg=hDlg;
  402.       SeekInProgress=false;
  403.       userIsTracking=false;
  404.       EnableWindow( GetDlgItem(hDlg, IDC_PLAY), true); 
  405.       EnableWindow( GetDlgItem(hDlg, IDOK), true); 
  406.       EnableWindow( GetDlgItem(hDlg, IDC_SEEKFIRST), true); 
  407.       EnableWindow( GetDlgItem(hDlg, IDC_SLIDER), true); 
  408.       EnableWindow( GetDlgItem(hDlg, IDC_STOP), true); 
  409.       SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_SETRANGE, (WPARAM) TRUE,(LPARAM) MAKELONG(0, nTrackBarRange)); 
  410.             
  411.             
  412.             play_frame_count = 0;
  413.             play_start_time = GetTickCount();
  414.  
  415.             playerTimer= SetTimer(hDlg,              // handle of window for timer messages
  416.                                      2,          // timer identifier
  417.                                    500,           // time-out value
  418.                                    NULL   // address of timer procedure
  419.                                    );
  420.  
  421.       // Snap the player at the botton of the main window
  422.       RECT rcMain;
  423.       GetWindowRect( hMainWnd, &rcMain );
  424.       WindowMove( hDlg, rcMain.left, rcMain.bottom );
  425.  
  426.  
  427.  
  428.       // Create default job
  429.       CreateDefaultJob();
  430.  
  431.       // Render list 
  432.       RenderBatchList(GetDlgItem(hDlg, IDC_LIST));
  433.  
  434.      
  435.       // listener
  436.       listener.SetDlg( hDlg );
  437.  
  438.       // Create player thread
  439.       FLASSERT(pMasterClock!=NULL);
  440.  
  441.  
  442.       // Create video player thread
  443.       pPlayer = new CPlayerThread( rs.video, hMainWnd, pMasterClock, pp.Get(), 
  444.                                    rs.conf.idctIndex, pprof.recons_progressive, &vidPanel );
  445.       pPlayer->Create();
  446.  
  447.       // Create audio player thread
  448.       pAudioPlayer = new CAudioThread( pMasterClock );
  449.       pAudioPlayer->Create();
  450.  
  451.       // If there are jobs select jump to the first one.
  452.       if(rs.vBatchList.size())
  453.       {
  454.         trackBarSpan = rs.vBatchList[0];
  455.         pPlayer->Seek( trackBarSpan.nStart );
  456.         RenderTrackbarSel(GetDlgItem(hDlg, IDC_SLIDER), &trackBarSpan );
  457.       }
  458.      
  459.                 return TRUE;
  460.         case WM_HSCROLL:
  461.             int nPos;
  462.             switch(LOWORD(wParam)){
  463.                 case TB_THUMBTRACK:
  464.           // Get position
  465.           // No need to serialize this.
  466.           userIsTracking = true;
  467.  
  468.           pAudioPlayer->Stop();
  469.  
  470.           nPos = SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_GETPOS, 0, 0);   
  471.           
  472.           nFilePos=(i64)(((double)nPos/1000.0)*(double)(i64)(rs.video->GetStreamSize()));
  473.           
  474.           // Seek the player to that position
  475.           pPlayer->SeekKeyFrame( nFilePos );
  476.           
  477.           play_frame_count = 0;
  478.           play_start_time = GetTickCount();
  479.           
  480.           break;
  481.                 case TB_THUMBPOSITION :
  482.           userIsTracking = false;
  483.                 break;
  484.             }
  485.             break;
  486.     case WM_NEWPPSETTINGS:
  487.       pps = *(TPPost *)wParam;
  488.       pPlayer->SetPPSettings( &pps );
  489.       pp.Set( &pps );
  490.             WindowClientResize( hMainWnd, pp.GetWidth() , pp.GetHeight() );
  491.       break;
  492.         case WM_COMMAND:
  493.     {
  494.             if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  495.             {
  496.         DeInitializePlayer(hDlg, pPlayer, pAudioPlayer, pMasterClock);
  497.         DestroyWindow(rs.hPlayerWnd);
  498.         rs.hPlayerWnd = NULL;
  499.                 return TRUE;
  500.             }
  501.       WORD wmId = LOWORD(wParam);
  502.       // Customized menues
  503.       if(wmId>=OUTPUT_POPUP_BASE && wmId<(OUTPUT_POPUP_BASE+MAX_OUT_PLUGINS+2))
  504.       {
  505.         if((wmId - OUTPUT_POPUP_BASE) < rs.plugs.OutPluginCount)
  506.           rs.selected_out_plug = wmId - 10000;
  507.         else if( (wmId - OUTPUT_POPUP_BASE) == rs.plugs.OutPluginCount + 1 ){
  508.           SendMessage( hMainWnd, WM_COMMAND, MAKEWPARAM(IDM_MPEG1OPTIONS,0), 0 );
  509.         }
  510.       }
  511.  
  512.             switch( LOWORD(wParam)){
  513.         case IDC_FLASKIT:
  514.           SendMessage( hMainWnd, WM_COMMAND, MAKEWPARAM(IDM_START2,0), 0 );       
  515.           break;
  516.         case IDC_AUDIOPLAYER:
  517.           ShowAudioPanel(pAudioPlayer);
  518.           break;
  519.         case IDC_VIDEOPANEL:
  520.           vidPanel.Show(pp.Get(), &listener );
  521.           break;
  522.         case IDC_SELECTOUTPUT:
  523.           ShowOutputPopup(hDlg, GetDlgItem(hDlg, IDC_SELECTOUTPUT));
  524.           break;
  525.         case IDC_SEEKFIRST:
  526.           pAudioPlayer->Stop();
  527.           pPlayer->SeekBeginning();
  528.                 break;
  529.         case IDC_SEEKEND:
  530.           pAudioPlayer->Stop();
  531.           pPlayer->SeekEnd();
  532.           break;
  533.         case IDC_PLAYBACK:
  534.           pAudioPlayer->Stop();
  535.           pPlayer->PlayBack();
  536.           break;
  537.                 case IDC_PLAY:
  538.           pAudioPlayer->Stop();
  539.           pPlayer->Stop();
  540.  
  541.           pMasterClock->Set(0);
  542.           pAudioPlayer->Seek( rs.video->GetSyncPoint( pPlayer->GetFrameStartPos() ));
  543.  
  544.           pPlayer->Play();
  545.           pAudioPlayer->Play();
  546.                     break;
  547.                 case IDC_STOP:
  548.           pAudioPlayer->Stop();
  549.           pPlayer->Stop();
  550.                     break;
  551.         case IDC_NEXTFRAME:
  552.           pAudioPlayer->Stop();
  553.           pPlayer->NextFrame();
  554.           break;
  555.         case IDC_PREVFRAME:
  556.           pAudioPlayer->Stop();
  557.           pPlayer->PrevFrame();
  558.           break;
  559.         case IDC_FASTFOR:
  560.           pAudioPlayer->Stop();
  561.           pPlayer->FastForward();
  562.           break;
  563.         case IDC_FASTBACK:
  564.           pAudioPlayer->Stop();
  565.           pPlayer->FastRewind();
  566.           break;
  567.         case IDC_STARTMARKER:
  568.           {
  569.             bool bWasPlaying;
  570.  
  571.             bWasPlaying = pPlayer->GetState() == CPlayerThread::stPlaying;
  572.  
  573.             if(bWasPlaying)
  574.             {
  575.               pAudioPlayer->Stop();
  576.               pPlayer->Stop();
  577.             }
  578.             
  579.             trackBarSpan.nStart = pPlayer->GetFrameStartPos();
  580.  
  581.             if(bWasPlaying)
  582.             {
  583.               pMasterClock->Set(0);
  584.               pAudioPlayer->Seek( rs.video->GetSyncPoint( trackBarSpan.nStart ));
  585.               
  586.               pPlayer->Play();
  587.               pAudioPlayer->Play();            
  588.             }
  589.  
  590.             if(trackBarSpan.nStart > trackBarSpan.nEnd)
  591.               trackBarSpan.nEnd   = rs.video->GetStreamSize();
  592.             RenderTrackbarSel(GetDlgItem(hDlg, IDC_SLIDER), &trackBarSpan );
  593.             
  594.           }
  595.           break;
  596.         case IDC_ENDMARKER:
  597.           trackBarSpan.nEnd = rs.video->GetStreamPos();
  598.           if(trackBarSpan.nEnd < trackBarSpan.nStart)
  599.             trackBarSpan.nStart = 0;
  600.           
  601.           RenderTrackbarSel(GetDlgItem(hDlg, IDC_SLIDER), &trackBarSpan );
  602.           break;
  603.         case IDC_GOSTARTMARKER:
  604.           pAudioPlayer->Stop();
  605.           pPlayer->Seek( trackBarSpan.nStart );
  606.           break;
  607.         case IDC_GOENDMARKER:
  608.           pAudioPlayer->Stop();
  609.           pPlayer->Seek( trackBarSpan.nEnd );
  610.           break;
  611.         case IDC_LISTADD:
  612.           rs.vBatchList.push_back(trackBarSpan);
  613.           RenderBatchList(GetDlgItem(hDlg, IDC_LIST));
  614.           break;
  615.         case IDC_LISTDELETEALL:
  616.           rs.vBatchList.clear();
  617.           RenderBatchList(GetDlgItem(hDlg, IDC_LIST));                      
  618.           break;
  619.         case IDC_LISTDELETE:
  620.           nSel = SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_GETCURSEL, 0, 0 );
  621.           if(nSel!=LB_ERR)
  622.           {
  623.             rs.vBatchList.erase( rs.vBatchList.begin() + nSel );
  624.             RenderBatchList(GetDlgItem(hDlg, IDC_LIST));            
  625.           }
  626.           break;
  627.         case IDC_LIST:
  628.           if(HIWORD(wParam)==LBN_SELCHANGE)
  629.           {
  630.             pAudioPlayer->Stop();
  631.             nSel = SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_GETCURSEL, 0, 0 );
  632.             trackBarSpan = rs.vBatchList[nSel];
  633.             RenderTrackbarSel(GetDlgItem(hDlg, IDC_SLIDER), &trackBarSpan);
  634.             pPlayer->Seek( trackBarSpan.nStart );
  635.           }
  636.           break;
  637.       }
  638.       }
  639.       break;
  640.  
  641.     case WM_DESTROY:
  642.  
  643.       vidPanel.Hide();
  644.       // return the settings to the current profile
  645.       FromPPostToConfig( &pprof, &pps );
  646.  
  647.       DeInitializePlayer(hDlg, pPlayer, pAudioPlayer, pMasterClock);
  648.       rs.hPlayerWnd = NULL;
  649.       break;
  650.     }
  651.     return FALSE;
  652. }
  653.  
  654.  
  655.