mpegator.cpp
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:5k
- /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
- Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
- Software license is located in file "COPYING"
- */
- #include "stdafx.h"
- #include "video_thread.h"
- #include "text_thread.h"
- #include "exceptions.h"
- // indicate that this file will hold values of OLE defs
- #include <initguid.h>
- // mpegator
- #include <mtruid.h>
- #include <mtrif.h>
- #include "mpegator.h"
- #include "protocol_thread.h"
- // #define TESTFILE
- #ifdef TESTFILE
- HANDLE f;
- #endif
- mpegator::mpegator( int argc, char **argv )
- : video_thread( argc, argv ), captureStarted( false ),
- mpeg_ops_mutex( "lock mpegator operation" ),
- wait_forobject_next_time( true )
- {
- }
- void mpegator::init()
- {
- // start OLE
- CoInitialize(NULL);
- HRESULT status = CoCreateInstance( CLSID_MtrMe, NULL, CLSCTX_SERVER,
- IID_IMtrCapture, (void**)&mpeg);
- if( FAILED(status) )
- {
- mpeg = NULL;
- protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
- throw VideoException( "OLE CoCreateInstance failed" );
- }
- if(mpeg->Open()!=S_OK)
- {
- char error_buffer[80];
- if(mpeg)
- {
- mpeg->GetLastError( error_buffer,
- sizeof(error_buffer)-1 );
- }
- mpeg->Release();
- mpeg = NULL;
- protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
- throw VideoException( "OLE Open failed: %s", error_buffer );
- }
- protocolThread->log( 1, "mpegator board initialized" );
- }
- mpegator::~mpegator()
- {
- shutdown();
- }
- void mpegator::shutdown()
- {
- wait_for_mutex wm( shutdown_mutex, 5 );
- if( shutdown_performed ) // already
- return;
- if( !mpeg )
- return;
- // look state
- MTRCAPINFO capinfo;
- mpeg->GetCapInfo( &capinfo );
- if( capinfo.state == MTRSTAT_PROCESS || capinfo.state == MTRSTAT_PAUSE )
- {
- mpeg->Stop();
- mpeg->CloseStreamEx();
- }
- else if( capinfo.state == MTRSTAT_STOP )
- mpeg->CloseStreamEx();
-
- mpeg->Close();
- mpeg->Release();
- mpeg = NULL;
- // and finally shtdown OLE
- CoUninitialize();
- protocolThread->log( 1, "mpegator board shutdown" );
- // protocol thread will wait until this flag is true
- shutdown_performed = true;
- }
- void mpegator::start_capture()
- {
- wait_for_mutex wm( mpeg_ops_mutex, 1 );
- if( captureStarted )
- return;
- if(mpeg->OpenStreamEx()!=S_OK)
- {
- protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
- throw VideoException( "Open stream failed" );
- }
- mpeg->Start();
- captureStarted = true;
- video_data_size = 0;
- protocolThread->log( 1, "capture started" );
- # ifdef TESTFILE
- f = CreateFile( "d:\tmp\test.mpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL );
- if( f == INVALID_HANDLE_VALUE )
- protocolThread->log( 0, "create file: %s", sys_errlist[ errno ] );
- # endif
- }
- void mpegator::stop_capture()
- {
- wait_for_mutex wm( mpeg_ops_mutex, 1 );
- if( !captureStarted )
- return;
- mpeg->Stop();
- mpeg->CloseStreamEx();
- captureStarted = FALSE;
- protocolThread->log( 1, "capture stopped" );
- # ifdef TESTFILE
- CloseHandle(f);
- # endif
- }
- void mpegator::check_for_new_data()
- {
- if( false == captureStarted )
- {
- protocolThread->log( 3, "capture is not started yet" );
- return;
- }
- // mutex'ed block
- {
- MTRSTREAMPTR sb;
- HRESULT res;
- wait_for_mutex wm( mpeg_ops_mutex, 1 );
- if( false == captureStarted )
- return;
-
- if( wait_forobject_next_time )
- WaitForSingleObject( mpeg->GetWaitHandle(), 100 );
- res = mpeg->StreamGetPtr( &sb, FALSE ); // do not wait for result
- if( res == S_FALSE )
- {
- protocolThread->log( 0, "throw VideoException, line %d", __LINE__ );
- throw VideoException( "OLE StreamGetPtr failed" );
- }
- if( sb.isUsed == false ) // || sb.actualSize < sb.bufferSize )
- {
- wait_forobject_next_time = true;
- // mpeg->StreamReleasePtr( &sb );
- return; // nothing
- }
- wait_forobject_next_time = false;
- if( sb.actualSize < sizeof( video_buffer ) - video_data_size )
- {
- memcpy( video_buffer + video_data_size, sb.bufferPtr, sb.actualSize );
- video_data_size += sb.actualSize;
- }
- else
- {
- memcpy( video_buffer + video_data_size, sb.bufferPtr,
- sizeof( video_buffer ) - video_data_size );
- video_data_size = sizeof( video_buffer );
- }
- // release
- mpeg->StreamReleasePtr( &sb );
- // mutex is released here
- }
- // if data is too small we should not send it immediately for
- // performance reasons
- if( sizeof( video_buffer ) - video_data_size > 25000 )
- return;
- protocolThread->log( 3, "new data from board, size is %d, to be send to %d"
- " targets", video_data_size, broadcast_targets.size() );
- Timeval now;
- now.now();
- // pick-up the new text as well - if any
- text_data *td = NULL;
- {
- // this is shared data:
- wait_for_mutex wm( lock_new_text, 1 );
- if( new_text.size() > 0 )
- {
- td = new_text.front();
- new_text.pop();
- }
- // mutex is released here
- }
- # ifdef TESTFILE
- DWORD dw;
- WriteFile( f, video_buffer, video_data_size, &dw, NULL );
- # endif
- broadcast_targetsT::iterator it;
- for( it = broadcast_targets.begin(); it != broadcast_targets.end(); it++ )
- {
- broadcast_target *target = *it;
- // simple pump data to TCP socket
- if( td == NULL )
- {
- target->send( video_buffer, video_data_size, "", now );
- }
- else
- {
- target->send( video_buffer, video_data_size, td->text, now );
- delete td; // don't need it anymore
- }
- }
- video_data_size = 0; // sent
- }