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

📄 videopin.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*+++ *******************************************************************\ 
* 
*  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 "VideoPin.h"
#include "Device.h"
#include "RegistryAccess.h"
#include "debug.h"
#include "stdlib.h"
#include "pindataranges.h"
#include "ivideodecoder.h"
#include "miscfuncs.h"
#include <mmsystem.h>

const ULONG VIDEO_FRAMES_TO_CYCLE = 10;



VideoPin::VideoPin(PKSPIN     p_ks_pin,
                   NTSTATUS  &status):
BasePin(p_ks_pin)
{
    _info_hdr = ((reinterpret_cast<KS_DATAFORMAT_VIDEOINFOHEADER*> 
                 (p_ks_pin->ConnectionFormat))->VideoInfoHeader);    

    _format = FormatData(&_info_hdr);
    PVOID   p_context = KsPinGetDevice(p_ks_pin)->Context;
    Device* p_device  = static_cast<Device*>(p_context);

    status = init(
        VIDEO_FRAMES_TO_CYCLE,
        _info_hdr.bmiHeader.biSizeImage,
        _info_hdr.AvgTimePerFrame);

    if(NT_SUCCESS(status))
    {
        p_ks_pin->StreamHeaderSize = sizeof KSSTREAM_HEADER + sizeof KS_FRAME_INFO;
    }

    //TODO: Set the resolution
    
}

DWORD VideoPin::getLineSize()
{
    return  _format.imageWidth()*2;
}

DWORD VideoPin::getLinesPerFrame()
{
    return abs(_format.imageHeight());
}

BOOLEAN VideoPin::isSingleFieldStream()
{
    DWORD height = abs(_format.imageHeight());

    DWORD max_single_field_height = 240;
    IVideoDecoder* p_decoder = _p_device->getVidDec();

    if(p_decoder->getVideoMode() == VIDEO_MODE_PAL)
    {
        max_single_field_height = 288;
    }

    return FALSE;
}

VOID VideoPin::start()
{
    IVideoDecoder* p_decoder = _p_device->getVidDec();
    p_decoder->setResolution(_format.imageWidth(), abs(_format.imageHeight()));

    RegistryAccess registry_access(_p_device->getPdo());
    DWORD board_type = POLARIS_BOARD_DVT;
    registry_access.readDword("BoardType", &board_type);

    if(board_type == POLARIS_BOARD_FPGA)
    {
        // enable TS1 data pin to output 656 to FPGA
        p_decoder->enableVideoOutput();
    }    
}


NTSTATUS VideoPin::dispatchCreate(PKSPIN  p_ks_pin,
                                  PIRP    p_irp)
{
    NTSTATUS status = STATUS_SUCCESS;

    p_ks_pin->Context = new VideoPin(p_ks_pin, status);

    if( !p_ks_pin->Context )
        return STATUS_INSUFFICIENT_RESOURCES;

    if( !NT_SUCCESS( status ) )
        delete (VideoPin*)p_ks_pin->Context;

    return status;
}


static BOOLEAN checkDimension( 
                           INT dimension,
                           INT lower_bound,
                           INT upper_bound,
                           INT step)
{
    if( dimension >= lower_bound && 
        dimension <= upper_bound &&
        (dimension - lower_bound) % step == 0 )
        return TRUE;
    
    return FALSE;
}


static BOOLEAN checkDimensions(
                            PKS_VIDEOINFOHEADER           p_info_to_check,
                            PKS_VIDEOINFOHEADER           p_info,
                            PKS_VIDEO_STREAM_CONFIG_CAPS  p_caps,
                            BOOLEAN                       softEncoderEnabled)
{
    FormatData format( p_info_to_check );

    if(!checkDimension( 
        format.imageWidth(),
        (softEncoderEnabled ? p_caps->MaxOutputSize.cx : p_caps->MinOutputSize.cx),
        p_caps->MaxOutputSize.cx,
        p_caps->OutputGranularityX))
    {
        return FALSE;
    }

    if(!checkDimension( 
        abs(format.imageHeight()),
        (softEncoderEnabled ? p_caps->MaxOutputSize.cy : p_caps->MinOutputSize.cy),
        p_caps->MaxOutputSize.cy,
        p_caps->OutputGranularityY))
    {
        return FALSE;
    }

    if((p_info_to_check->bmiHeader.biCompression != p_info->bmiHeader.biCompression) ||
        (p_info_to_check->bmiHeader.biBitCount != p_info->bmiHeader.biBitCount))
    {
        return FALSE;
    }

    return TRUE;
}

NTSTATUS VideoPin::dispatchSetFormat(PKSPIN            p_ks_pin, 
                                     PKSDATAFORMAT     p_old_data_format,
                                     PKSMULTIPLE_ITEM  p_attr_list,
                                     PKSDATARANGE      p_range,
                                     PKSATTRIBUTE_LIST p_attr_range)
{ 
    if( IsEqualGUID( p_ks_pin->ConnectionFormat->Specifier,
                     KSDATAFORMAT_SPECIFIER_VIDEOINFO ) )
    {
        if( p_ks_pin->ConnectionFormat->FormatSize < 
            sizeof KS_DATAFORMAT_VIDEOINFOHEADER )
                return STATUS_INVALID_PARAMETER;

        KS_DATAFORMAT_VIDEOINFOHEADER *p_new_format = 
            (KS_DATAFORMAT_VIDEOINFOHEADER*)
            p_ks_pin->ConnectionFormat;

        KS_DATARANGE_VIDEO *p_data_range = 
            (KS_DATARANGE_VIDEO*)p_range;

        PVOID   p_context = KsPinGetDevice(p_ks_pin)->Context;
        Device* p_device  = static_cast<Device*>(p_context);

        // Check that we support the requested image dimensions.
        if(!checkDimensions( 
            &p_new_format->VideoInfoHeader,
            &p_data_range->VideoInfoHeader,
            &p_data_range->ConfigCaps,
            p_device->IsSoftEncoderEnabled()))
        {
            return STATUS_NO_MATCH;
        }


        // Check that the image size in the info 
        // header matches its dimensions
        if( p_new_format->VideoInfoHeader.bmiHeader.biSizeImage !=
            KS_DIBSIZE( p_new_format->VideoInfoHeader.bmiHeader ) )
        {
            return STATUS_INVALID_PARAMETER;
        }

        // If p_old_data_format != NULL it means that dispatchCreate()
        // has already been called and "this dispatch contains the 
        // actual surface parameters" see DDK->Data Range Intersections 
        // in AVStream.  Since only the stride should change we need 
        // make sure this is the case, and return fail otherwise.
        if(p_old_data_format)
        {
            //If we are in a running state, we can't change the format
            if(KsPinGetFirstCloneStreamPointer(p_ks_pin))
            {
                DbgLogError(("SetDataFormat after buffers received\n"));
                return STATUS_INVALID_DEVICE_STATE;
            }
            
            VideoPin*   p_vid_pin  = (VideoPin*)p_ks_pin->Context;
            FormatData  old_format = p_vid_pin->_format;
            FormatData  new_format(&p_new_format->VideoInfoHeader);

            // Make sure only the stride changed
            if((p_new_format->VideoInfoHeader.AvgTimePerFrame !=p_vid_pin->_info_hdr.AvgTimePerFrame) ||
                (abs(new_format.imageHeight()) != abs( old_format.imageHeight())) ||
                (new_format.imageWidth() != old_format.imageWidth())  ||
                (new_format.bitCount() != old_format.bitCount()) ||
                (new_format.compression() != old_format.compression()))

⌨️ 快捷键说明

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