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 + -
显示快捷键?