tffdshowvideoinputpin.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 577 行 · 第 1/2 页
SVN-BASE
577 行
/* * Copyright (c) 2003-2006 Milan Cutka * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include "stdafx.h"#include "TffdshowVideoInputPin.h"#include "ffdebug.h"#include "dsutil.h"#include "TvideoCodec.h"#include "theora/theora.h"#include "TffDecoderVideo.h"#include "Tconvert.h"#include "TffdshowVideo.h"#include "TsubtitlesFile.h"#include "libavcodec/bitstream.h"#include "ffdshow_mediaguids.h"//================================== TffdshowVideoInputPin =================================TffdshowVideoInputPin::TffdshowVideoInputPin(TCHAR *objectName,TffdshowVideo *Ifv,HRESULT *phr) :TinputPin(objectName,Ifv->filter,phr,L"In"), allocator(Ifv->filter,phr), fv(Ifv), video(NULL){ usingOwnAllocator=false; supdvddec=fv->deci->getParam2(IDFF_supDVDdec) && fv->deci->getParam2(IDFF_mpg2); done();}TffdshowVideoInputPin::~TffdshowVideoInputPin(){ done();}HRESULT TffdshowVideoInputPin::CheckMediaType(const CMediaType* mt){ if (mt->majortype!=MEDIATYPE_Video && !(mt->majortype==MEDIATYPE_DVD_ENCRYPTED_PACK && supdvddec)) return VFW_E_TYPE_NOT_ACCEPTED; if (mt->subtype==MEDIASUBTYPE_DVD_SUBPICTURE) return VFW_E_TYPE_NOT_ACCEPTED; BITMAPINFOHEADER *hdr=NULL,hdr0; if (mt->formattype==FORMAT_VideoInfo) { VIDEOINFOHEADER *vih=(VIDEOINFOHEADER*)mt->pbFormat; hdr=&vih->bmiHeader; fixMPEGinAVI(hdr->biCompression); } else if (mt->formattype==FORMAT_VideoInfo2) { VIDEOINFOHEADER2 *vih2=(VIDEOINFOHEADER2*)mt->pbFormat; hdr=&vih2->bmiHeader; fixMPEGinAVI(hdr->biCompression); } else if (mt->formattype==FORMAT_MPEGVideo) { MPEG1VIDEOINFO *mpeg1info=(MPEG1VIDEOINFO*)mt->pbFormat; hdr=&(hdr0=mpeg1info->hdr.bmiHeader); hdr->biCompression=FOURCC_MPG1; } else if (mt->formattype==FORMAT_MPEG2Video) { MPEG2VIDEOINFO *mpeg2info=(MPEG2VIDEOINFO*)mt->pbFormat; hdr=&(hdr0=mpeg2info->hdr.bmiHeader); if (hdr->biCompression==0) hdr->biCompression=FOURCC_MPG2; } else if (mt->formattype==FORMAT_TheoraIll) { sTheoraFormatBlock *oggFormat=(sTheoraFormatBlock*)mt->pbFormat; hdr=&hdr0; hdr->biWidth=oggFormat->width;hdr->biHeight=oggFormat->height; hdr->biCompression=FOURCC_THEO; } else if (mt->formattype==FORMAT_RLTheora) { hdr=&hdr0; hdr->biCompression=FOURCC_THEO; } else return VFW_E_TYPE_NOT_ACCEPTED; char_t pomS[60]; DPRINTF(_l("TffdshowVideoInputPin::CheckMediaType: %s, %i, %i"),fourcc2str(hdr2fourcc(hdr,&mt->subtype),pomS,60),hdr->biWidth,hdr->biHeight); return fv->getVideoCodecId(hdr,&mt->subtype,NULL)==CODEC_ID_NONE?VFW_E_TYPE_NOT_ACCEPTED:S_OK;}STDMETHODIMP TffdshowVideoInputPin::ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt){ CAutoLock cObjectLock(m_pLock); if (m_Connected) { CMediaType mt(*pmt); BITMAPINFOHEADER bih, bihCur; ExtractBIH(mt, &bih); ExtractBIH(m_mt, &bihCur); // HACK: for the intervideo filter, when it tries to change the pitch from 720 to 704... //if(bihCur.biWidth != bih.biWidth && bihCur.biHeight == bih.biHeight) // return S_OK; return (CheckMediaType(&mt) != S_OK || SetMediaType(&mt) != S_OK/* || !initVideo(mt)*/) ? VFW_E_TYPE_NOT_ACCEPTED : S_OK; // TODO: send ReceiveConnection downstream } else { HRESULT hr=fv->deci->checkInputConnect(pConnector); if (hr!=S_OK) return hr; } return TinputPin::ReceiveConnection(pConnector, pmt);}bool TffdshowVideoInputPin::init(const CMediaType &mt){ bool neroavc=false,truncated=false; if (mt.formattype==FORMAT_VideoInfo) { VIDEOINFOHEADER *vih=(VIDEOINFOHEADER*)mt.pbFormat; biIn.bmiHeader=vih->bmiHeader; pictIn.setSize(vih->bmiHeader.biWidth,abs(vih->bmiHeader.biHeight)); fixMPEGinAVI(biIn.bmiHeader.biCompression); } else if (mt.formattype==FORMAT_VideoInfo2) { VIDEOINFOHEADER2 *vih2=(VIDEOINFOHEADER2*)mt.pbFormat; biIn.bmiHeader=vih2->bmiHeader; pictIn.setSize(vih2->bmiHeader.biWidth,abs(vih2->bmiHeader.biHeight)); pictIn.setDar(Rational(vih2->dwPictAspectRatioX,vih2->dwPictAspectRatioY)); DPRINTF(_l("TffdshowVideoInputPin::initVideo: darX:%i, darY:%i"),vih2->dwPictAspectRatioX,vih2->dwPictAspectRatioY); fixMPEGinAVI(biIn.bmiHeader.biCompression); } else if (mt.formattype==FORMAT_MPEGVideo) { MPEG1VIDEOINFO *mpeg1info=(MPEG1VIDEOINFO*)mt.pbFormat; biIn.bmiHeader=mpeg1info->hdr.bmiHeader;biIn.bmiHeader.biCompression=FOURCC_MPG1; pictIn.setSize(std::max(mpeg1info->hdr.rcSource.right,mpeg1info->hdr.bmiHeader.biWidth),std::max(mpeg1info->hdr.rcSource.bottom,mpeg1info->hdr.bmiHeader.biHeight)); } else if (mt.formattype==FORMAT_MPEG2Video) { MPEG2VIDEOINFO *mpeg2info=(MPEG2VIDEOINFO*)mt.pbFormat; biIn.bmiHeader=mpeg2info->hdr.bmiHeader; pictIn.setSize(std::max(mpeg2info->hdr.rcSource.right,mpeg2info->hdr.bmiHeader.biWidth),std::max(mpeg2info->hdr.rcSource.bottom,mpeg2info->hdr.bmiHeader.biHeight)); pictIn.setDar(Rational(mpeg2info->hdr.dwPictAspectRatioX,mpeg2info->hdr.dwPictAspectRatioY)); if (biIn.bmiHeader.biCompression==0) biIn.bmiHeader.biCompression=FOURCC_MPG2; else { biIn.bmiHeader.biCompression=FCCupper(biIn.bmiHeader.biCompression); neroavc=true; } } else if (mt.formattype==FORMAT_TheoraIll) { memset(&biIn,0,sizeof(biIn)); sTheoraFormatBlock *oggFormat=(sTheoraFormatBlock*)mt.pbFormat; biIn.bmiHeader.biCompression=FOURCC_THEO; pictIn.setSize(biIn.bmiHeader.biWidth=oggFormat->width,biIn.bmiHeader.biHeight=oggFormat->height); pictIn.setDar(Rational(oggFormat->aspectNumerator,oggFormat->aspectDenominator)); biIn.bmiHeader.biBitCount=12; } else if (mt.formattype==FORMAT_RLTheora) { struct RLTheora { VIDEOINFOHEADER hdr; DWORD headerSize[3]; // 0: Header, 1: Comment, 2: Codebook }; const RLTheora *rl=(const RLTheora*)mt.pbFormat; GetBitContext gb; init_get_bits(&gb,(const uint8_t*)(rl+1),rl->headerSize[0]); int ptype = get_bits(&gb, 8); if (!(ptype&0x80)) return false; biIn.bmiHeader.biCompression=FOURCC_THEO; skip_bits(&gb, 6*8); /* "theora" */ int major=get_bits(&gb,8); /* version major */ int minor=get_bits(&gb,8); /* version minor */ int micro=get_bits(&gb,8); /* version micro */ int theora = (major << 16) | (minor << 8) | micro; if (theora < 0x030200) { ;//flipped_image = 1; } biIn.bmiHeader.biWidth = get_bits(&gb, 16) << 4; biIn.bmiHeader.biHeight = get_bits(&gb, 16) << 4; pictIn.setSize(biIn.bmiHeader.biWidth,biIn.bmiHeader.biHeight); skip_bits(&gb, 24); /* frame width */ skip_bits(&gb, 24); /* frame height */ skip_bits(&gb, 8); /* offset x */ skip_bits(&gb, 8); /* offset y */ skip_bits(&gb, 32); /* fps numerator */ skip_bits(&gb, 32); /* fps denumerator */ Rational sample_aspect_ratio; sample_aspect_ratio.num = get_bits(&gb, 24); /* aspect numerator */ sample_aspect_ratio.den = get_bits(&gb, 24); /* aspect denumerator */ pictIn.setSar(sample_aspect_ratio); } else return false; REFERENCE_TIME avgTimePerFrame0=getAvgTimePerFrame(mt); avgTimePerFrame=avgTimePerFrame0?avgTimePerFrame0:400000; char_t pomS[60]; DPRINTF(_l("TffdshowVideoInputPin::initVideo: %s, width:%i, height:%i, aspectX:%i, aspectY:%i"),fourcc2str(hdr2fourcc(&biIn.bmiHeader,&mt.subtype),pomS,60) ,pictIn.rectFull.dx,pictIn.rectFull.dy,pictIn.rectFull.dar().num,pictIn.rectFull.dar().den);again: if (video) {delete video;codec=video=NULL;} codecId=(CodecID)fv->getVideoCodecId(&biIn.bmiHeader,&mt.subtype,&biIn.bmiHeader.biCompression); if (codecId==CODEC_ID_NONE) return false; if (codecId==CODEC_ID_H264) { Textradata extradata(mt,16); if (extradata.size) decodeH264SPS(extradata.data,extradata.size,pictIn); } if (mpeg4_codec(codecId)) { Textradata extradata(mt,16); if (extradata.size) decodeMPEG4pictureHeader(extradata.data,extradata.size,pictIn); } else if (mpeg12_codec(codecId)) { Textradata extradata(mt,16); if (extradata.size) { bool isH264; if (decodeMPEGsequenceHeader(biIn.bmiHeader.biCompression==FOURCC_MPG2,extradata.data,extradata.size,pictIn,&isH264) && isH264) { biIn.bmiHeader.biCompression=FOURCC_H264; truncated=true; goto again; } } } if (!fv->sink) rawDecode=true; else { fv->initCodecSettings(); codec=video=TvideoCodecDec::initDec(fv->deci,fv->sink,codecId,biIn.bmiHeader.biCompression,mt); if (!video) return false; else { static const GUID CLSID_NeroDigitalParser={0xE206E4DE,0xA7EE,0x4A62,0xB3,0xE9,0x4F,0xBC,0x8F,0xE8,0x4C,0x73}; static const GUID CLSID_HalliMatroskaFile={0x55DA30FC,0xF16B,0x49FC,0xBA,0xA5,0xAE,0x59,0xFC,0x65,0xF8,0x2D}; //neroavc=biIn.bmiHeader.biCompression==FOURCC_AVC1 && (searchPreviousFilter(this,CLSID_NeroDigitalParser) || searchPreviousFilter(this,CLSID_HalliMatroskaFile)); if (!video->beginDecompress(pictIn,biIn.bmiHeader.biCompression,mt,(neroavc?TvideoCodecDec::SOURCE_NEROAVC:0)|(truncated?TvideoCodecDec::SOURCE_TRUNCATED:0))) { delete video;codec=video=NULL; return false; } } rawDecode=raw_codec(codecId); } allocator.NotifyMediaType(mt); strippacket=!!(mt.majortype==MEDIATYPE_DVD_ENCRYPTED_PACK); return true;}void TffdshowVideoInputPin::done(void){ if (video) delete video;codec=video=NULL; memset(&biIn,0,sizeof(biIn));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?