📄 transportstream.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 + -