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;
00102
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
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
00152
00153 mFFDShowVideoFormatBlock->AvgTimePerFrame = locTimePerBlock / locSamplesPerBlock;
00154
00155
00156
00157 __int64 locFPSec = (UNITS / locTimePerBlock) * locSamplesPerBlock;
00158
00159
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;
00166 mFFDShowVideoFormatBlock->bmiHeader.biClrUsed = 0;
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;
00176 mFFDShowVideoFormatBlock->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00177 mFFDShowVideoFormatBlock->bmiHeader.biSizeImage = (locHeight * locWidth * locBPSample) / 8;
00178 mFFDShowVideoFormatBlock->bmiHeader.biWidth = locWidth;
00179 mFFDShowVideoFormatBlock->bmiHeader.biXPelsPerMeter = 2000;
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
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
00204
00205
00206 if ((mLastKnownTimeBase != inPacket->startTime()) && (inPacket->startTime() != -1)) {
00207 mLastKnownTimeBase = inPacket->startTime();
00208 mLastTimeStamp = mLastKnownTimeBase * mFFDShowVideoFormatBlock->AvgTimePerFrame;
00209
00210
00211
00212
00213 mGranuleOffset = 0;
00214 }
00215
00216
00217
00218
00219 LONGLONG locStart = mLastTimeStamp - mSourcePin->CurrentStartTime();
00220 LONGLONG locEnd = locStart + mFFDShowVideoFormatBlock->AvgTimePerFrame;
00221 mGranuleOffset++;
00222
00223
00224
00225
00226 mLastTimeStamp = (locEnd >= mLastTimeStamp) ? locEnd
00227 : mLastTimeStamp;
00228
00229
00230
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
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 }