📄 parse656data.cpp
字号:
break;
case ANCILLARY_DID_VBI_FIELD2:
//We aren't handling field 2 for now.
break;
default:
break;
}
_ancillary_packet.clearData();
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Parse656Data::submitDataBuffer(PBYTE p_buffer, DWORD buffer_size,BYTE type)
{
//First take care of any data left over from the last buffer
DWORD bytes_parsed = 0;
DWORD tmp = 0;
BYTE sav_eav = 0;
switch(type)
{
case 0: ///raw video
{
if(_is_partial_line)
{
//Handle the case where we were working on a partial line
sav_eav = _last_sav;
}
//Handle the case where an ancillary packet starts at the beginning of the buffer.
//(Ancillay packets start with 00 FF FF)
else if((p_buffer[0] == 0x00) && (p_buffer[1] == 0xFF) && (p_buffer[2] == 0xFF))
{
//We check for ancillary packets after any EAV.
sav_eav = EAV_VBLANK_FIELD1;
}
else
{
//Check for a SAV/EAV overlapping the buffer boundary
sav_eav = findBoundarySAV_EAV(p_buffer, &bytes_parsed);
}
sav_eav&=0xF0;
//Get the first line if we have some portion of an SAV/EAV from the last buffer
// or a partial line
if(sav_eav)
{
bytes_parsed += getLine(
sav_eav, //SAV/EAV
p_buffer + bytes_parsed, //p_buffer
buffer_size - bytes_parsed); //buffer size
}
//Now parse data that is completely in this buffer
BOOLEAN is_partial_line = FALSE;
while(bytes_parsed < buffer_size)
{
DWORD bytes_used;
sav_eav = findNextSAV_EAV(
p_buffer + bytes_parsed, //p_buffer
buffer_size - bytes_parsed, //buffer size
&bytes_used); //Receives bytes used to get SAV/EAV
bytes_parsed += bytes_used;
sav_eav&=0xF0;
if(sav_eav && (bytes_parsed < buffer_size))
{
bytes_parsed += getLine(
sav_eav, //SAV/EAV
p_buffer + bytes_parsed, //p_buffer
buffer_size - bytes_parsed); //buffer size
}
}
//Save the last four bytes of the buffer so we can check the buffer boundary
// condition next time
RtlCopyMemory(_end_of_buffer_bytes, p_buffer + buffer_size - 4, 4);
break;
}
case 1: //audio
#if 0 //DBG
dumpfile(p_buffer, buffer_size);
#endif
_audio_iis_buffer.completeBuffers(p_buffer, buffer_size);
break;
case 2: // vbi
case 3: //sliced cc
BYTE flag;
flag = findBoundaryheader(p_buffer, &bytes_parsed);
if(flag)
{
while(bytes_parsed<buffer_size)
{
DWORD bytes_used = 0;
DWORD tmp_buffer_size =0;
flag = findNextheader(p_buffer + bytes_parsed, buffer_size - bytes_parsed,&bytes_used);
tmp_buffer_size = bytes_used; //vbi size in every field
while(tmp_buffer_size)
{
//TODO tmp_buffer_size = _vbi_parse_buffer.parsevbiBuffer(p_buffer + bytes_parsed, tmp_buffer_size,_field_num);
}
_field_num^=1; //modified field
bytes_parsed += bytes_used;
}
}
RtlCopyMemory(_end_of_buffer_bytes, p_buffer + buffer_size - 4, 4);
break;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//If there is an SAV/EAV pattern overlapping a buffer boundary, find it here.
//
BYTE Parse656Data::findBoundarySAV_EAV(PBYTE p_buffer, PDWORD p_bytes_used)
{
*p_bytes_used = 0;
//Create an array of the last 4 bytes of the last buffer and the first
// 4 bytes of the current buffer.
BYTE boundary_bytes[8];
RtlCopyMemory(boundary_bytes, _end_of_buffer_bytes, 4);
RtlCopyMemory(boundary_bytes + 4, p_buffer, 4);
//Check for the SAV/EAV in the boundary buffer
DWORD bytes_used;
BYTE sav_eav = findNextSAV_EAV((PBYTE)&boundary_bytes, 8, &bytes_used);
if(sav_eav)
{
//found a boundary SAV/EAV. Updates the bytes used to reflect
// only those used in the new buffer
*p_bytes_used = bytes_used - 4;
}
return sav_eav;
}
/////////////////////////////////////////////////////////////////////////////////////////
//SAV and EAV codes follow the pattern 0xFF 0x00 0x00 0xXX where XX is the SAV or EAV
// marking the beginning of ending of a line.
//
// This function finds the next SAV or EAV in the buffer
//
BYTE Parse656Data::findNextSAV_EAV(PBYTE p_buffer, DWORD buffer_size, PDWORD p_bytes_used)
{
//Don't search if the buffer size is less than 4. It causes a page fault since
// buffer_size - 4 evaluates to a large number in that case.
if(buffer_size < 4)
{
*p_bytes_used = buffer_size;
return 0;
}
for(DWORD i = 0;i < (buffer_size - 4); i++)
{
if((p_buffer[i] == 0xFF) &&
(p_buffer[i+1] == 0x00) &&
(p_buffer[i+2] == 0x00))
{
*p_bytes_used = i+4;
BYTE sav_eav = p_buffer[i+3];
//Special case: SAV_PARTIAL_ANCILLARY is not a real SAV, and should never show up
// in a 656 stream as an SAV. However, it can show up in audio data. So, if
// we find it, ignore it.
if(sav_eav != SAV_PARTIAL_ANCILLARY)
{
return sav_eav;
}
}
}
*p_bytes_used = buffer_size;
return 0;
}
BYTE Parse656Data::findBoundaryheader(PBYTE p_buffer, PDWORD p_bytes_used)
{
*p_bytes_used = 0;
//Create an array of the last 4 bytes of the last buffer and the first
// 4 bytes of the current buffer.
BYTE boundary_bytes[8];
RtlCopyMemory(boundary_bytes, _end_of_buffer_bytes, 4);
RtlCopyMemory(boundary_bytes + 4, p_buffer, 4);
//Check for the SAV/EAV in the boundary buffer
DWORD bytes_used;
BYTE flag = findNextheader((PBYTE)&boundary_bytes, 8, &bytes_used);
if(flag)
{
//found a boundary SAV/EAV. Updates the bytes used to reflect
// only those used in the new buffer
*p_bytes_used = bytes_used - 4;
}
return flag;
}
/////////////////////////////////////////////////////////////////////////////////////////
//SAV and EAV codes follow the pattern 0xFF 0x00 0x00 0xXX where XX is the SAV or EAV
// marking the beginning of ending of a line.
//
// This function finds the next SAV or EAV in the buffer
//
BYTE Parse656Data::findNextheader(PBYTE p_buffer, DWORD buffer_size, PDWORD p_bytes_used)
{
//Don't search if the buffer size is less than 4. It causes a page fault since
// buffer_size - 4 evaluates to a large number in that case.
if(buffer_size < 4)
{
*p_bytes_used = buffer_size;
return 0;
}
for(DWORD i = 0;i < (buffer_size - 4); i++)
{
if((p_buffer[i] == 0x00) &&
(p_buffer[i+1] == 0xff) &&
(p_buffer[i+2] == 0xff))
{
*p_bytes_used = i+4;
BYTE flag = p_buffer[i+3];
//Special case: SAV_PARTIAL_ANCILLARY is not a real SAV, and should never show up
// in a 656 stream as an SAV. However, it can show up in audio data. So, if
// we find it, ignore it.
return flag;
}
}
*p_bytes_used = buffer_size;
return 0;
}
VOID Parse656Data::setAudioPin(BasePin * p_pin)
{
_audio_iis_buffer.setPin(p_pin);
}
VOID Parse656Data::releaseAudioPin()
{
_audio_iis_buffer.releasePin();
}
VOID Parse656Data::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\\audio.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
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
ZwClose(_file_handle);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -