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

📄 parse656data.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        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 + -