mpegator.cpp
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:5k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
  2.    Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
  3.    Software license is located in file "COPYING"
  4. */
  5. #include "stdafx.h"
  6. #include "video_thread.h"
  7. #include "text_thread.h"
  8. #include "exceptions.h"
  9. // indicate that this file will hold values of OLE defs
  10. #include <initguid.h>
  11. // mpegator
  12. #include <mtruid.h>
  13. #include <mtrif.h>
  14. #include "mpegator.h"
  15. #include "protocol_thread.h"
  16. // #define TESTFILE
  17. #ifdef TESTFILE
  18. HANDLE f;
  19. #endif
  20. mpegator::mpegator( int argc, char **argv )
  21.   : video_thread( argc, argv ), captureStarted( false ),
  22.     mpeg_ops_mutex( "lock mpegator operation" ), 
  23.     wait_forobject_next_time( true )
  24. {
  25. }
  26. void mpegator::init()
  27. {
  28.   // start OLE 
  29.   CoInitialize(NULL);
  30.   HRESULT status = CoCreateInstance( CLSID_MtrMe, NULL, CLSCTX_SERVER,
  31.      IID_IMtrCapture, (void**)&mpeg);
  32.   if( FAILED(status) )
  33.     {
  34.       mpeg = NULL;
  35.       protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
  36.       throw VideoException( "OLE CoCreateInstance failed" );
  37.     }
  38.   if(mpeg->Open()!=S_OK)
  39.     {
  40.       char error_buffer[80];
  41.       if(mpeg)
  42. {
  43.   mpeg->GetLastError( error_buffer,
  44.       sizeof(error_buffer)-1 );
  45. }
  46.       mpeg->Release();
  47.       mpeg = NULL;
  48.       protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
  49.       throw VideoException( "OLE Open failed: %s", error_buffer );
  50.     }
  51.   protocolThread->log( 1, "mpegator board initialized" );
  52. }
  53. mpegator::~mpegator()
  54. {
  55.   shutdown();
  56. }
  57. void mpegator::shutdown()
  58. {
  59.   wait_for_mutex wm( shutdown_mutex, 5 );
  60.   if( shutdown_performed ) // already
  61.     return;
  62.   if( !mpeg )
  63.     return;
  64.   // look state
  65.   MTRCAPINFO capinfo;
  66.   mpeg->GetCapInfo( &capinfo );
  67.   if( capinfo.state == MTRSTAT_PROCESS || capinfo.state == MTRSTAT_PAUSE )
  68.     {
  69.       mpeg->Stop();
  70.       mpeg->CloseStreamEx();
  71.     }
  72.   else if( capinfo.state == MTRSTAT_STOP )
  73.     mpeg->CloseStreamEx();
  74.     
  75.   mpeg->Close();
  76.   mpeg->Release();
  77.   mpeg = NULL;
  78.   // and finally shtdown OLE
  79.   CoUninitialize();
  80.   protocolThread->log( 1, "mpegator board shutdown" );
  81.   // protocol thread will wait until this flag is true
  82.   shutdown_performed = true;
  83. }
  84. void mpegator::start_capture()
  85. {
  86.   wait_for_mutex wm( mpeg_ops_mutex, 1 );
  87.   if( captureStarted )
  88.     return;
  89.   if(mpeg->OpenStreamEx()!=S_OK)
  90.     {
  91.       protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
  92.       throw VideoException( "Open stream failed" );
  93.     }
  94.   mpeg->Start();
  95.   captureStarted = true;
  96.   video_data_size = 0;
  97.   protocolThread->log( 1, "capture started" );
  98. # ifdef TESTFILE
  99.   f = CreateFile( "d:\tmp\test.mpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  100. FILE_ATTRIBUTE_NORMAL, NULL );
  101.   if( f == INVALID_HANDLE_VALUE )
  102.     protocolThread->log( 0, "create file: %s", sys_errlist[ errno ] );
  103. # endif
  104. }
  105. void mpegator::stop_capture()
  106. {
  107.   wait_for_mutex wm( mpeg_ops_mutex, 1 );
  108.   if( !captureStarted )
  109.     return;
  110.   mpeg->Stop();
  111.   mpeg->CloseStreamEx();
  112.   captureStarted = FALSE;
  113.   protocolThread->log( 1, "capture stopped" );
  114. # ifdef TESTFILE
  115.   CloseHandle(f);
  116. # endif
  117. }
  118. void mpegator::check_for_new_data()
  119. {
  120.   if( false == captureStarted )
  121.     {
  122.       protocolThread->log( 3, "capture is not started yet" );
  123.       return;
  124.     }
  125.   // mutex'ed block
  126.   {
  127.     MTRSTREAMPTR sb;
  128.     HRESULT res;
  129.     wait_for_mutex wm( mpeg_ops_mutex, 1 );
  130.     if( false == captureStarted )
  131.       return;
  132.   
  133.     if( wait_forobject_next_time )
  134.       WaitForSingleObject( mpeg->GetWaitHandle(), 100 );
  135.     res = mpeg->StreamGetPtr( &sb, FALSE ); // do not wait for result
  136.     if( res == S_FALSE )
  137.       {
  138. protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
  139. throw VideoException( "OLE StreamGetPtr failed" );
  140.       }
  141.     if( sb.isUsed == false ) // || sb.actualSize < sb.bufferSize )
  142.       {
  143. wait_forobject_next_time = true;
  144. // mpeg->StreamReleasePtr( &sb );
  145. return;  // nothing
  146.       }
  147.     wait_forobject_next_time = false;
  148.     if( sb.actualSize < sizeof( video_buffer ) - video_data_size )
  149.       {
  150. memcpy( video_buffer + video_data_size, sb.bufferPtr, sb.actualSize );
  151. video_data_size += sb.actualSize;
  152.       }
  153.     else
  154.       {
  155. memcpy( video_buffer + video_data_size, sb.bufferPtr, 
  156. sizeof( video_buffer ) - video_data_size );
  157. video_data_size = sizeof( video_buffer );
  158.       }
  159.     // release
  160.     mpeg->StreamReleasePtr( &sb );
  161.     // mutex is released here
  162.   }
  163.   // if data is too small we should not send it immediately for 
  164.   // performance reasons
  165.   if( sizeof( video_buffer ) - video_data_size > 25000 )
  166.     return;
  167.   protocolThread->log( 3, "new data from board, size is %d, to be send to %d"
  168.        " targets", video_data_size, broadcast_targets.size() );
  169.   Timeval now;
  170.   now.now();
  171.   // pick-up the new text as well - if any
  172.   text_data *td = NULL;
  173.   {
  174.     // this is shared data:
  175.     wait_for_mutex wm( lock_new_text, 1 );
  176.     if( new_text.size() > 0 )
  177.       {
  178. td = new_text.front();
  179. new_text.pop();
  180.       }
  181.     // mutex is released here
  182.   }
  183. # ifdef TESTFILE
  184.   DWORD dw;
  185.   WriteFile( f, video_buffer, video_data_size, &dw, NULL );
  186. # endif
  187.   broadcast_targetsT::iterator it;
  188.   for( it = broadcast_targets.begin(); it != broadcast_targets.end(); it++ )
  189.     {
  190.       broadcast_target *target = *it;
  191.       // simple pump data to TCP socket
  192.       if( td == NULL )
  193. {
  194.   target->send( video_buffer, video_data_size, "", now );
  195. }
  196.       else
  197. {
  198.   target->send( video_buffer, video_data_size, td->text, now );
  199.   delete td; // don't need it anymore
  200. }
  201.     }
  202.   video_data_size = 0; // sent
  203. }