⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transportstream.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
字号:
/*+++ *******************************************************************\ 
* 
*  Copyright and Disclaimer: 
*  
*     --------------------------------------------------------------- 
*     This software is provided "AS IS" without warranty of any kind, 
*     either expressed or implied, including but not limited to the 
*     implied warranties of noninfringement, merchantability and/or 
*     fitness for a particular purpose.
*     --------------------------------------------------------------- 
*   
*     Copyright (c) 2008 Conexant Systems, Inc. 
*     All rights reserved. 
*
\******************************************************************* ---*/ 
#include "transportStream.h"

#define TS_PACKET_SIZE      188
#define MAX_USB_PACKETS     320

/////////////////////////////////////////////////////////////////////////////////////////
TransportStream::TransportStream():
	_p_pin(NULL),
	_file_handle(NULL),
	_buffer_offset(0)
{
    RtlZeroBytes((PVOID)_p_zero_data_buf,TS_PACKET_SIZE);
	KeInitializeMutex(&_mutex, 0);
}

TransportStream::~TransportStream()
{
	if(_p_pin)
    {
		releasePin(_p_pin);
		_p_pin = NULL;
	}
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID TransportStream::Initialize(PolarisUsbInterface* pFx2Firmware)
{
    _p_current_buffer = NULL;
    _buffer_offset=0;
    _p_usb_firmware = pFx2Firmware;
    _reset_streaming_counter = 0;
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID TransportStream::setPin(BasePin* p_pin)
{
	KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );
    
    _p_pin = p_pin;

     _p_current_buffer = NULL;

     _ts_stream_state = 0;
 
    KeReleaseMutex(&_mutex, FALSE);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID TransportStream::releasePin(BasePin* p_pin)
{
    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );
    
    _p_pin = NULL;
    _p_current_buffer = NULL;
 
    KeReleaseMutex(&_mutex, FALSE);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID TransportStream::notifyPinFormatChange(BasePin* p_pin)
{
    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );

    if(_ts_stream_state)
        _ts_stream_state = 0;
    else
        _ts_stream_state = 1;

    KeReleaseMutex(&_mutex, FALSE);

    if(_ts_stream_state)
    {
        submitDataBuffer(NULL,TS_PACKET_SIZE * 5);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID TransportStream::submitDataBuffer(PBYTE p_buffer, DWORD buffer_size)
{	

   // Acquire the lock first to protect _p_pin value
   KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );

   if(_ts_stream_state)  // paused
   {

      if( _p_current_buffer)
	     {
         _p_current_buffer = NULL;
      }
 
      _p_pin->releaseClones();

      KeReleaseMutex(&_mutex, FALSE);
 
      return;

    }

    if(p_buffer == NULL)
    {
         // we don't have good buffer just return after releasing mutex
         KeReleaseMutex(&_mutex, FALSE);        
         return;
    }

#if 0//DBG

	dumpfile(p_buffer, buffer_size);

#endif

	do {
           if( _p_pin)
           {
		      //Get a buffer to copy the data into
		        if(!_p_current_buffer)
		        {
			        _p_current_buffer = _p_pin->getNextBuffer();
		        }

		        if( _p_current_buffer)
		        {			    
			       //copy the data from usb buffer to stream buffer
			        if(_buffer_offset+buffer_size > _p_current_buffer->OffsetOut.Count )
			        {
				        ULONG tempSize = _p_current_buffer->OffsetOut.Count - _buffer_offset;
				        RtlCopyMemory(_p_current_buffer->OffsetOut.Data+ _buffer_offset, p_buffer ,tempSize);
				        _buffer_offset += tempSize;
				        buffer_size -= tempSize;		
				        p_buffer += tempSize;
			        }
			        else
			        {
				        RtlCopyMemory(_p_current_buffer->OffsetOut.Data+ _buffer_offset, p_buffer , buffer_size);
				        _buffer_offset += buffer_size;
				        buffer_size = 0;				
			        }
			    
			        if(_buffer_offset == _p_current_buffer->OffsetOut.Count)
			        {
				        // complete the buffer
				        //_p_current_buffer->OffsetOut.Remaining = _buffer_offset;
                        _p_current_buffer->StreamHeader->DataUsed = _buffer_offset;
				        _p_pin->onBufferComplete(FIELD_INVALID);			
				        _p_current_buffer = NULL;
				        _buffer_offset = 0;
			        }			    
		        }
                else
                {
                    // we don't have any stream buffers, so leave the loop
                    buffer_size = 0;
                }
        }
        else
        {
            // we don't have any valid pin, so leave the loop
            buffer_size = 0;
        }

	}while (buffer_size );

    // Release the Lock
	KeReleaseMutex(&_mutex, FALSE);

}

VOID TransportStream::dumpfile(PBYTE p_data, DWORD buffer_size )
{
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK status_block;

    UNICODE_STRING file_name;
 
    RtlInitUnicodeString(&file_name, L"\\systemroot\\ts.dat");

    LARGE_INTEGER FilePos; 
    FILE_STANDARD_INFORMATION FileInformation; 


    OBJECT_ATTRIBUTES attributes;
	InitializeObjectAttributes(
        &attributes, 
        &file_name, 
        OBJ_CASE_INSENSITIVE, 
        NULL, 
        NULL);

    status = ZwCreateFile(
        &_file_handle,                                                 //FileHandle
        FILE_APPEND_DATA | FILE_WRITE_DATA,                        //DesiredAccess
        &attributes,                                            //ObjectAttributes
        &status_block,                                          //IoStatusBlock
        NULL,                                                   //AllocationSize
        FILE_ATTRIBUTE_NORMAL,                                                      //FileAttributes
        0,                                        //ShareAccess
        FILE_OPEN_IF,                                              //CreateDisposition
        FILE_SYNCHRONOUS_IO_NONALERT, //CreateOptions
        NULL,                                                   //EaBuffer
        0);                                                     //EaLength

    if(!_file_handle)
    {
        return;
    }
	
    status = ZwQueryInformationFile( 
               _file_handle, 
               &status_block, 
               &FileInformation, 
               sizeof (FileInformation), 
               FileStandardInformation 
               ); 

    FilePos = FileInformation.EndOfFile;    

    if (!NT_SUCCESS(status)) 
    { 
        FilePos.QuadPart = 0; 
    } 
 
    status = ZwWriteFile(
        _file_handle,       //file handle
        NULL,               //event
        NULL,               //apc routine
        NULL,               //apc context
        &status_block,      // io status block
        p_data,             //buffer
        buffer_size,        //Size of buffer
        &FilePos,               //Offset in the file to write
        NULL);              //key

    if(NT_SUCCESS(status))
    {
    	         
    }

    ZwClose(_file_handle);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -