FFDShowVideoStream.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 #include "stdafx.h"
00033 #include "ffdshowvideostream.h"
00034 
00035 
00036 
00037 FFDShowVideoStream::FFDShowVideoStream(OggPage* inBOSPage, OggDemuxSourceFilter* inOwningFilter, bool inAllowSeek)
00038         :       OggStream(inBOSPage, inOwningFilter, inAllowSeek)
00039         ,       mFFDShowVideoFormatBlock(NULL)
00040         ,       mLastTimeStamp(0)
00041         ,       mLastKnownTimeBase(0)
00042         ,       mGranuleOffset(0)
00043 {
00044         InitCodec(inBOSPage->getStampedPacket(0));
00045         //debugLog.open("g:\\logs\\ffd_dump.out", ios_base::out);
00046 }
00047 
00048 FFDShowVideoStream::~FFDShowVideoStream(void)
00049 {
00050         //debugLog.close();
00051         delete mFFDShowVideoFormatBlock;
00052 }
00053 
00054 bool FFDShowVideoStream::InitCodec(StampedOggPacket* inOggPacket) {
00055         //Can probably abstract this out of here too !
00056         mCodecHeaders = new StreamHeaders;
00057         mCodecHeaders->mCodecType = StreamHeaders::FFDSHOW_VIDEO;
00058         mCodecHeaders->addPacket((StampedOggPacket*)inOggPacket->clone());
00059         mHeaderPack = (StampedOggPacket*)inOggPacket->clone();
00060 
00061         unsigned char* locPackData = inOggPacket->packetData();
00062         mFourCCCode = MAKEFOURCC(locPackData[9], locPackData[10], locPackData[11], locPackData[12]);
00063         mMediaSubTypeGUID = (GUID)(FOURCCMap(mFourCCCode));
00064 
00065         unsigned char* locFourCCString = new unsigned char[5];
00066         for (int i = 0; i < 4; i++) {
00067                 locFourCCString[i] = locPackData[9+i];
00068         }
00069         locFourCCString[4] = 0;
00070 
00071         string locPinName = (char*)locFourCCString;
00072         locPinName = "FOURCC( " + locPinName + " ) out";
00073         mPinName = StringHelper::toWStr(locPinName);
00074 
00075         //What to do with commment fields ??
00076         mNumHeadersNeeded = 1;
00077         //mFirstRun = false;
00078         return true;
00079 }
00080 
00081 
00082 bool FFDShowVideoStream::deliverCodecHeaders() {
00083         StampedOggPacket* locPacket = NULL;
00084 
00085         //TODO::: Why 2 ?
00086         for (unsigned long i = 2; i < mCodecHeaders->numPackets(); i++) {
00087                 locPacket = mCodecHeaders->getPacket(i);
00088 
00089                 dispatchPacket(locPacket);
00090         }
00091         return true;
00092 
00093 }
00094 wstring FFDShowVideoStream::getPinName() {
00095         
00096         return mPinName;
00097 }
00098 
00099 bool FFDShowVideoStream::createFormatBlock() {
00100         mFFDShowVideoFormatBlock = new VIDEOINFOHEADER;
00102         //unsigned char* locIdentHeader = mCodecHeaders->getPacket(0)->packetData();
00106 
00107         //mTheoraFormatBlock->theoraVersion = (FLACMath::charArrToULong(locIdentHeader + 7)) >>8;
00108         //mTheoraFormatBlock->width = (FLACMath::charArrToUShort(locIdentHeader + 10)) * 16;
00109         //mTheoraFormatBlock->height = (FLACMath::charArrToUShort(locIdentHeader + 12)) * 16;
00110         //mTheoraFormatBlock->frameWidth = (FLACMath::charArrToULong(locIdentHeader + 14)) >>8;
00111         //mTheoraFormatBlock->frameHeight = (FLACMath::charArrToULong(locIdentHeader + 17)) >>8;
00112         //mTheoraFormatBlock->xOffset = locIdentHeader[20];
00113         //mTheoraFormatBlock->yOffset = locIdentHeader[21];
00114         //mTheoraFormatBlock->frameRateNumerator = FLACMath::charArrToULong(locIdentHeader + 22);
00115         //mTheoraFormatBlock->frameRateDenominator = FLACMath::charArrToULong(locIdentHeader + 26);
00116         //mTheoraFormatBlock->aspectNumerator = (FLACMath::charArrToULong(locIdentHeader + 30)) >>8;
00117         //mTheoraFormatBlock->aspectDenominator = (FLACMath::charArrToULong(locIdentHeader + 33)) >>8;
00118         //mTheoraFormatBlock->colourSpace = locIdentHeader[36];
00119         //mTheoraFormatBlock->targetBitrate = (FLACMath::charArrToULong(locIdentHeader + 37)) >>8;
00120         //mTheoraFormatBlock->targetQuality = (locIdentHeader[40]) >> 2;
00122         //mTheoraFormatBlock->maxKeyframeInterval= 0;
00123 
00124 
00125 
00126         //FORMAT OF HEADER IN OGG BOS
00127         //-----------------------------------------
00128         //0             -               8               =               STRING          Stream Type (char[8] is NULL)
00129         //9             -               12              =               STRING          Sub Type (FOURCC)
00130         //13    -               16              =               INT32           Size of structure ???
00131         //17    -               24              =               INT64           Time per "unit" in DSHOW UNITS
00132         //25    -               32              =               INT64           Samples per "unit"
00133         //33    -               36              =               INT32           Deefault length ????? in media type ?? WTF ?
00134         //37    -               40              =               INT32           Buffer Size
00135         //41    -               42              =               INT16           Bits per sample
00136         //43    -               44              =               -----           HOLE IN DATA
00137         //45    -               48              =               INT32           Video Width
00138         //49    -               52              =               INT32           Video Height
00139 
00140 
00141  
00142 
00143         //------------------------------------------
00144 
00145         
00146         __int64 locTimePerBlock = iLE_Math::CharArrToInt64(mHeaderPack->packetData() + 17);
00147 
00148         
00149         __int64 locSamplesPerBlock = iLE_Math::CharArrToInt64(mHeaderPack->packetData() + 25);
00150 
00151         //debugLog<<"t/block = "<<locTimePerBlock<<"        Sam/block = "<<locSamplesPerBlock<<endl;
00152 
00153         mFFDShowVideoFormatBlock->AvgTimePerFrame = locTimePerBlock / locSamplesPerBlock;
00154 
00155         //debugLog<<"Time per frame = "<<mFFDShowVideoFormatBlock->AvgTimePerFrame<<endl;
00156 
00157         __int64 locFPSec = (UNITS / locTimePerBlock) * locSamplesPerBlock;
00158 
00159         //debugLog<<"Rate = "<<locFPSec<<" fps"<<endl;
00160         unsigned short locBPSample = ((unsigned char)(mHeaderPack->packetData()[41])) + (((unsigned short)(mHeaderPack->packetData()[42])) * 256);
00161 
00162         
00163         
00164         mFFDShowVideoFormatBlock->bmiHeader.biBitCount = locBPSample;
00165         mFFDShowVideoFormatBlock->bmiHeader.biClrImportant = 0;   //All colours important
00166         mFFDShowVideoFormatBlock->bmiHeader.biClrUsed = 0;        //Use max colour depth
00167         mFFDShowVideoFormatBlock->bmiHeader.biCompression = mFourCCCode;
00168 
00169         unsigned long locHeight = iLE_Math::charArrToULong(mHeaderPack->packetData() + 49);
00170         unsigned long locWidth =  iLE_Math::charArrToULong(mHeaderPack->packetData() + 45);
00171 
00172         mFFDShowVideoFormatBlock->dwBitRate = 0;
00173 
00174         mFFDShowVideoFormatBlock->bmiHeader.biHeight = locHeight;
00175         mFFDShowVideoFormatBlock->bmiHeader.biPlanes = 1;    //Must be 1
00176         mFFDShowVideoFormatBlock->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    //????? Size of what ?
00177         mFFDShowVideoFormatBlock->bmiHeader.biSizeImage = (locHeight * locWidth * locBPSample) / 8;    //Size in bytes of image ??
00178         mFFDShowVideoFormatBlock->bmiHeader.biWidth = locWidth;
00179         mFFDShowVideoFormatBlock->bmiHeader.biXPelsPerMeter = 2000;   //Fuck knows
00180         mFFDShowVideoFormatBlock->bmiHeader.biYPelsPerMeter = 2000;   //" " " " " 
00181         
00182         mFFDShowVideoFormatBlock->rcSource.top = 0;
00183         mFFDShowVideoFormatBlock->rcSource.bottom = locHeight;
00184         mFFDShowVideoFormatBlock->rcSource.left = 0;
00185         mFFDShowVideoFormatBlock->rcSource.right = locWidth;
00186 
00187         mFFDShowVideoFormatBlock->rcTarget.top = 0;
00188         mFFDShowVideoFormatBlock->rcTarget.bottom = locHeight;
00189         mFFDShowVideoFormatBlock->rcTarget.left = 0;
00190         mFFDShowVideoFormatBlock->rcTarget.right = locWidth;
00191 
00192         mFFDShowVideoFormatBlock->dwBitErrorRate=0;
00193         return true;
00194 }
00195 
00196 
00197 bool FFDShowVideoStream::dispatchPacket(StampedOggPacket* inPacket) {
00198         //This is to get aroudn the extra mystery byte that ogg encapsulated divx gets at the start :|
00199         unsigned char* locBuff = new unsigned char[inPacket->packetSize() - 1];
00200         memcpy((void*)locBuff, (const void*) (inPacket->packetData() + 1), inPacket->packetSize() - 1);
00201         
00202 
00203         //This is to help ffdshow handle timestamps the way it likes them.
00204         //Everytime, the start time changes, we record it and reset the granule counter (frame count)
00205         //This lets ogm stuff be seekable cleanly.
00206         if ((mLastKnownTimeBase != inPacket->startTime()) && (inPacket->startTime() != -1)) {
00207                 mLastKnownTimeBase = inPacket->startTime();
00208                 mLastTimeStamp = mLastKnownTimeBase * mFFDShowVideoFormatBlock->AvgTimePerFrame;
00209                 //debugLog<<"Last Time base set  to  "<<mLastKnownTimeBase<<endl;
00210                 //debugLog<<"Last time stamp set to "<<mLastTimeStamp<<endl;
00211 
00212                 //Granule Offset may not be needed any more.
00213                 mGranuleOffset = 0;
00214         }
00215 
00216         //debugLog<<"Packet stamps = "<<inPacket->startTime() << " - "<<inPacket->endTime()<<endl;
00217 
00218         //debugLog<<"m_tStart = "<<mSourcePin->CurrentStartTime()<<endl;
00219         LONGLONG locStart = mLastTimeStamp - mSourcePin->CurrentStartTime();
00220         LONGLONG locEnd = locStart + mFFDShowVideoFormatBlock->AvgTimePerFrame;
00221         mGranuleOffset++;
00222 
00223         //debugLog<<"Time Stamps = "<<locStart<<" - "<<locEnd<<endl;
00224         //debugLog<<"Granule offset " << mGranuleOffset<<endl;
00225         
00226         mLastTimeStamp = (locEnd >= mLastTimeStamp)             ?       locEnd
00227                                                                                                         :       mLastTimeStamp;
00228 
00229         //debugLog << "Packet :    Start   =   "<<locStart<<"     -   End   =   "<<locEnd<<endl;
00230                                                                                                                                                                         //We should only be delivering full packets here.
00231         StampedOggPacket* locPack = new StampedOggPacket(locBuff, inPacket->packetSize() - 1, false, false, locStart, locEnd, StampedOggPacket::DIRECTSHOW);
00232         return OggStream::dispatchPacket(locPack);
00233 }
00234 BYTE* FFDShowVideoStream::getFormatBlock() {
00235 
00236         return (BYTE*)mFFDShowVideoFormatBlock;
00237 }
00238 
00239 GUID FFDShowVideoStream::getMajorTypeGUID() {
00240         return MEDIATYPE_Video;
00241 }
00242 unsigned long FFDShowVideoStream::getFormatBlockSize() {
00243         //Do something
00244         return sizeof(VIDEOINFOHEADER);
00245 }
00246 GUID FFDShowVideoStream::getFormatGUID() {
00247         return FORMAT_VideoInfo;
00248 }
00249 GUID FFDShowVideoStream::getSubtypeGUID() {
00250         return mMediaSubTypeGUID;
00251 }
00252 
00253 LONGLONG FFDShowVideoStream::getCurrentPos() {
00254         return 0;
00255 }
00256 
00257 unsigned long FFDShowVideoStream::getNumBuffers() {
00258         return FFDSHOW_VIDEO_NUM_BUFFERS;
00259 }
00260 unsigned long FFDShowVideoStream::getBufferSize() {
00261         return FFDSHOW_VIDEO_BUFFER_SIZE;
00262 }

Generated on Tue Feb 15 14:54:19 2005 for oggdsf by  doxygen 1.3.9