00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00046 }
00047
00048 FFDShowVideoStream::~FFDShowVideoStream(void)
00049 {
00050
00051 delete mFFDShowVideoFormatBlock;
00052 }
00053
00054 bool FFDShowVideoStream::InitCodec(StampedOggPacket* inOggPacket) {
00055
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
00076 mNumHeadersNeeded = 1;
00077
00078 return true;
00079 }
00080
00081
00082 bool FFDShowVideoStream::deliverCodecHeaders() {
00083 StampedOggPacket* locPacket = NULL;
00084
00085
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;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 __int64 locTimePerBlock = iLE_Math::CharArrToInt64(mHeaderPack->packetData() + 17);
00125
00126
00127 __int64 locSamplesPerBlock = iLE_Math::CharArrToInt64(mHeaderPack->packetData() + 25);
00128
00129
00130
00131 mFFDShowVideoFormatBlock->AvgTimePerFrame = locTimePerBlock / locSamplesPerBlock;
00132
00133
00134
00135 __int64 locFPSec = (UNITS / locTimePerBlock) * locSamplesPerBlock;
00136
00137
00138 unsigned short locBPSample = ((unsigned char)(mHeaderPack->packetData()[41])) + (((unsigned short)(mHeaderPack->packetData()[42])) * 256);
00139
00140
00141
00142 mFFDShowVideoFormatBlock->bmiHeader.biBitCount = locBPSample;
00143 mFFDShowVideoFormatBlock->bmiHeader.biClrImportant = 0;
00144 mFFDShowVideoFormatBlock->bmiHeader.biClrUsed = 0;
00145 mFFDShowVideoFormatBlock->bmiHeader.biCompression = mFourCCCode;
00146
00147 unsigned long locHeight = iLE_Math::charArrToULong(mHeaderPack->packetData() + 49);
00148 unsigned long locWidth = iLE_Math::charArrToULong(mHeaderPack->packetData() + 45);
00149
00150 mFFDShowVideoFormatBlock->dwBitRate = 0;
00151
00152 mFFDShowVideoFormatBlock->bmiHeader.biHeight = locHeight;
00153 mFFDShowVideoFormatBlock->bmiHeader.biPlanes = 1;
00154 mFFDShowVideoFormatBlock->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00155 mFFDShowVideoFormatBlock->bmiHeader.biSizeImage = (locHeight * locWidth * locBPSample) / 8;
00156 mFFDShowVideoFormatBlock->bmiHeader.biWidth = locWidth;
00157 mFFDShowVideoFormatBlock->bmiHeader.biXPelsPerMeter = 2000;
00158 mFFDShowVideoFormatBlock->bmiHeader.biYPelsPerMeter = 2000;
00159
00160 mFFDShowVideoFormatBlock->rcSource.top = 0;
00161 mFFDShowVideoFormatBlock->rcSource.bottom = locHeight;
00162 mFFDShowVideoFormatBlock->rcSource.left = 0;
00163 mFFDShowVideoFormatBlock->rcSource.right = locWidth;
00164
00165 mFFDShowVideoFormatBlock->rcTarget.top = 0;
00166 mFFDShowVideoFormatBlock->rcTarget.bottom = locHeight;
00167 mFFDShowVideoFormatBlock->rcTarget.left = 0;
00168 mFFDShowVideoFormatBlock->rcTarget.right = locWidth;
00169
00170 mFFDShowVideoFormatBlock->dwBitErrorRate=0;
00171 return true;
00172 }
00173
00174
00175 bool FFDShowVideoStream::dispatchPacket(StampedOggPacket* inPacket) {
00176
00177 unsigned long locLenBytes = ((((unsigned long)inPacket->packetData()[0]) >> 4) | (inPacket->packetData()[0] & 2)) >> 1;
00178 unsigned char* locBuff = new unsigned char[inPacket->packetSize() - 1];
00179 memcpy((void*)locBuff, (const void*) (inPacket->packetData() + locLenBytes), inPacket->packetSize() - locLenBytes);
00180
00181
00182
00183
00184
00185 if ((mLastKnownTimeBase != inPacket->startTime()) && (inPacket->startTime() != -1)) {
00186 mLastKnownTimeBase = inPacket->startTime();
00187 mLastTimeStamp = mLastKnownTimeBase * mFFDShowVideoFormatBlock->AvgTimePerFrame;
00188
00189
00190
00191
00192 mGranuleOffset = 0;
00193 }
00194
00195
00196
00197
00198 LONGLONG locStart = mLastTimeStamp - mSourcePin->CurrentStartTime();
00199 LONGLONG locEnd = locStart + mFFDShowVideoFormatBlock->AvgTimePerFrame;
00200 mGranuleOffset++;
00201
00202
00203
00204
00205 mLastTimeStamp = (locEnd >= mLastTimeStamp) ? locEnd
00206 : mLastTimeStamp;
00207
00208
00209
00210 StampedOggPacket* locPack = new StampedOggPacket(locBuff, inPacket->packetSize() - locLenBytes, false, false, locStart, locEnd, StampedOggPacket::DIRECTSHOW);
00211 return OggStream::dispatchPacket(locPack);
00212 }
00213 BYTE* FFDShowVideoStream::getFormatBlock() {
00214
00215 return (BYTE*)mFFDShowVideoFormatBlock;
00216 }
00217
00218 GUID FFDShowVideoStream::getMajorTypeGUID() {
00219 return MEDIATYPE_Video;
00220 }
00221 unsigned long FFDShowVideoStream::getFormatBlockSize() {
00222
00223 return sizeof(VIDEOINFOHEADER);
00224 }
00225 GUID FFDShowVideoStream::getFormatGUID() {
00226 return FORMAT_VideoInfo;
00227 }
00228 GUID FFDShowVideoStream::getSubtypeGUID() {
00229 return mMediaSubTypeGUID;
00230 }
00231
00232 LONGLONG FFDShowVideoStream::getCurrentPos() {
00233 return 0;
00234 }
00235
00236 unsigned long FFDShowVideoStream::getNumBuffers() {
00237 return FFDSHOW_VIDEO_NUM_BUFFERS;
00238 }
00239 unsigned long FFDShowVideoStream::getBufferSize() {
00240 return FFDSHOW_VIDEO_BUFFER_SIZE;
00241 }