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

📄 videoenc.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *  Openmysee
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include <streams.h>
#include <dvdmedia.h>
#include <qedit.h>
#include "wmcodecconst.h"
#include "wmcodeciface.h"
#include "encappErr.h"

#include "macros.h"
#include "VideoEncParams.h"
#include "videoenc.h"

#include "Capture.h"

//////////////////////////////////////////////////////////////////////////////
//
// MakeVideoOutputType
//
//////////////////////////////////////////////////////////////////////////////
HRESULT MakeVideoOutputType(IMediaObject   *pDMO,    \
                            AM_MEDIA_TYPE  *pmtIn,   \
                            CVideoEncParams *pParams, \
                            AM_MEDIA_TYPE  *pmt      ) {
    
    HRESULT             hr                   = S_OK;
    VIDEOINFOHEADER2    *pvih2               = NULL;
    VIDEOINFOHEADER     vih;
    IWMCodecPrivateData *pWMCodecPrivateData = NULL;
    DWORD               cbPrivateData        = 0;
    BYTE                *pbPrivateData       = NULL;
    BYTE                *pNewFormat          = NULL;
    
    if( pDMO == NULL || pmtIn == NULL || pParams == NULL || pmt == NULL )
        return E_INVALIDARG;
    
    if( pmtIn->pbFormat == NULL || pmtIn->cbFormat <= 0 )
        return E_INVALIDARG;
    
    // make up a partial media type
    pmt->majortype            = MEDIATYPE_Video;
    pmt->formattype           = FORMAT_VideoInfo;
    pmt->bFixedSizeSamples    = FALSE;
    pmt->bTemporalCompression = TRUE;
    
    if( pmtIn->formattype == FORMAT_VideoInfo ){
        vih = *(VIDEOINFOHEADER*)pmtIn->pbFormat; 
    } else if( pmtIn->formattype == FORMAT_VideoInfo2 ){
        pvih2 = (VIDEOINFOHEADER2*)pmtIn->pbFormat;
        vih.rcSource        = pvih2->rcSource;
        vih.rcTarget        = pvih2->rcTarget;
        vih.AvgTimePerFrame = pvih2->AvgTimePerFrame;
        vih.bmiHeader       = pvih2->bmiHeader;
    } else
        return E_VIDEO_INVALID_INPUT_TYPE;
    
    vih.dwBitRate            = (DWORD)pParams->nBitrate;
    vih.dwBitErrorRate       = 0;
    vih.bmiHeader.biPlanes   = 1;
    vih.bmiHeader.biBitCount = 24;
    
    switch( pParams->dwTag ){
    case WMCFOURCC_WMV3:
        pmt->subtype = WMCMEDIASUBTYPE_WMV3;
        vih.bmiHeader.biCompression = WMCFOURCC_WMV3;
        break;
    default:
        return E_VIDEO_COMPRESSION_NOT_SUPPORTED;
    }
    
    //use the fake format above to get the private data
    pmt->pbFormat = (BYTE*)&vih;
    pmt->cbFormat = sizeof( vih );
    pmt->pUnk = NULL;
    
    hr = pDMO->QueryInterface(IID_IWMCodecPrivateData, (void**)&pWMCodecPrivateData);    
    if( FAILED( hr ) )
        return E_NO_PRIVATE_DATA;
    
    hr = pWMCodecPrivateData->SetPartialOutputType( pmt );
    if( FAILED( hr ) ){
        SAFERELEASE( pWMCodecPrivateData );
        return E_PARTIAL_TYPE_REJECTED;;
    }
    
    hr = pWMCodecPrivateData->GetPrivateData( NULL, &cbPrivateData );
    if( FAILED( hr ) ){
        SAFERELEASE( pWMCodecPrivateData );        
        return E_NO_PRIVATE_DATA_COUNT;
    }
    
    if( cbPrivateData != 0 ){
        pbPrivateData = new BYTE[ cbPrivateData ];
        if( pbPrivateData == NULL ){
            SAFERELEASE( pWMCodecPrivateData );
            return E_OUTOFMEMORY;
        }
        
        // get the private data
        hr = pWMCodecPrivateData->GetPrivateData( pbPrivateData, &cbPrivateData );
        SAFERELEASE( pWMCodecPrivateData );
        if( FAILED( hr ) ) 
            return E_PRIVATE_DATA_FAILED;
    }
    
    //modify the media type accordingly
    pNewFormat = (BYTE*)CoTaskMemAlloc( sizeof( VIDEOINFOHEADER) + cbPrivateData );
    if( pNewFormat == NULL ){
        SAFEDELETE( pbPrivateData );
        return E_OUTOFMEMORY;
    }
    
    memcpy( pNewFormat, pmt->pbFormat, sizeof( VIDEOINFOHEADER));
    if( pbPrivateData != NULL )
        memcpy( pNewFormat + sizeof( VIDEOINFOHEADER), pbPrivateData, cbPrivateData);
    SAFEDELETE( pbPrivateData );
    
    pmt->pbFormat = pNewFormat;
    pmt->cbFormat = sizeof( VIDEOINFOHEADER) + cbPrivateData;
    ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biSize += cbPrivateData;
    
    return S_OK;
}

//////////////////////////////////////////////////////////////////////////////
//
// SetVideoTypes
//
//////////////////////////////////////////////////////////////////////////////
HRESULT SetVideoTypes( IMediaObject   *pDMO,    \
                      AM_MEDIA_TYPE  *pmtIn,   \
                      CVideoEncParams *pParams, \
                      AM_MEDIA_TYPE  *pmtOut,  \
                      DWORD *pcbIn,            \
                      DWORD *pcbOut ){
    HRESULT hr;
    DWORD   dwDummy;
    
    //Now we can make the output type...
    hr = MakeVideoOutputType( pDMO, pmtIn, pParams, pmtOut );
    if( FAILED( hr ) )
    {
//        ON_FAIL("Failed MakeVideoOutputType\r\n", hr)
            return hr;
    }
    
    //... and set it on the DMO just to check whether it is accepted or not
    hr = pDMO->SetOutputType(0, pmtOut, 0);
    if( FAILED( hr ) )
    {
  //      ON_FAIL("Failed SetOutputType\r\n", hr)
            return hr;
    }
    
    //     
    hr = pDMO->GetInputSizeInfo( 0, pcbIn, &dwDummy, &dwDummy);
    if( FAILED(hr) )
    {
   //     ON_FAIL("Failed GetInputSizeInfo\r\n", hr)
            return hr;
    }
    
    hr = pDMO->GetOutputSizeInfo( 0, pcbOut, &dwDummy);
    if( FAILED( hr ) )
    {
 //       ON_FAIL("Failed GetOutputSizeInfo\r\n", hr)
            return hr;
    }
    
    return hr;
} 

//////////////////////////////////////////////////////////////////////////////
//
// SetVideoParams
//
//////////////////////////////////////////////////////////////////////////////
HRESULT SetVideoParams( IMediaObject *pDMO, CVideoEncParams *pParams ){
    HRESULT      hr = S_OK;
    VARIANT      varg;
    BSTR         bstrIn;
    IPropertyBag *pPropertyBag = NULL;
    
    if( pDMO == NULL || pParams == NULL )
        return E_INVALIDARG;
    
    do {
        // Get the IPropertyBag IF and set the appropriate params
        hr = pDMO->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);
        if( FAILED( hr ) ){
            break;
        }
        
        //set the encoder in VBR mode if required
        if( pParams->fIsVBR == TRUE ){
            ::VariantInit(&varg);
            varg.vt      = VT_BOOL;
            varg.boolVal = TRUE;
            
            hr = pPropertyBag->Write( g_wszWMVCVBREnabled, &varg );
            if( FAILED( hr ) ){
                hr = E_VIDEO_VBR_NOT_SUPPORTED;
                break;
            }
            
            ::VariantInit(&varg);
            varg.vt = VT_I4;
            varg.lVal = pParams->nVBRQuality;
            hr = pPropertyBag->Write( g_wszWMVCVBRQuality, &varg );
            if( FAILED( hr ) ){
                hr = E_VBR_QUALITY_REJECTED;
                break;
            }
        }
        
        // set the bitrate if not VBR
        if( pParams->fIsVBR == FALSE ){
            ::VariantInit(&varg);
            varg.vt = VT_I4;
            varg.lVal = pParams->nBitrate;
            hr = pPropertyBag->Write( g_wszWMVCAvgBitrate, &varg );
            if( FAILED( hr ) ){
                hr = E_VIDEO_BITRATE_REJECTED;
                break;
            }
        }
        
        // set the buffer window
        ::VariantInit(&varg);
        varg.vt = VT_I4;
        varg.lVal = pParams->nBufferDelay;
        hr = pPropertyBag->Write( g_wszWMVCVideoWindow, &varg );
        if( FAILED( hr ) ){
            hr = E_VIDEO_BUFFER_REJECTED;
            break;

⌨️ 快捷键说明

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