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 "OggRawAudioInserterInputPin.h"
00034
00035 OggRawAudioInserterInputPin::OggRawAudioInserterInputPin(AbstractTransformFilter* inParentFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes)
00036 : AbstractTransformInputPin(inParentFilter, inFilterLock, inOutputPin, NAME("OggRawAudioInserterInputPin"), L"PCM In", inAcceptableMediaTypes)
00037
00038 , mUptoFrame(0)
00039 , mNumBufferedBytes(0)
00040 , mWorkingBuffer(NULL)
00041 , mFrameByteWidth(0)
00042 , mFramesPerPacket(0)
00043 , mBytesPerPacket(0)
00044 , mSentHeaders(false)
00045 {
00046
00047 mWorkingBuffer = new unsigned char[WORKING_BUFFER_SIZE];
00048 }
00049
00050 OggRawAudioInserterInputPin::~OggRawAudioInserterInputPin(void)
00051 {
00052
00053 DestroyCodec();
00054
00055 delete[] mWorkingBuffer;
00056 }
00057
00058
00059 unsigned long OggRawAudioInserterInputPin::identifyFormat()
00060 {
00061 switch(((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.bitsPerSample) {
00062 case 8:
00063 return FMT_U8;
00064 case 16:
00065 return FMT_S16_LE;
00066 default:
00067 return 0xffffffff;
00068 }
00069 }
00070 bool OggRawAudioInserterInputPin::makeMainHeader(unsigned char** outBuff, unsigned long* outHeaderSize)
00071 {
00072 const unsigned long MAIN_HEADER_SIZE = 28;
00073 unsigned char* retBuff = new unsigned char[MAIN_HEADER_SIZE];
00074
00075
00076 memcpy((void*)retBuff, "PCM ", 8);
00077
00078 retBuff[8] = 0;
00079 retBuff[9] = 0;
00080 retBuff[10] = 0;
00081 retBuff[11] = 0;
00082
00083
00084 unsigned long locFormat = identifyFormat();
00085 iBE_Math::ULongToCharArr(locFormat, &retBuff[12]);
00086
00087
00088 iBE_Math::ULongToCharArr(((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.samplesPerSec, &retBuff[16]);
00089
00090
00091 retBuff[20] = ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.bitsPerSample;
00092
00093
00094 retBuff[21] = ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.numChannels;
00095
00096
00097 retBuff[22] = (mFramesPerPacket & 0xff00) >> 8;
00098 retBuff[23] = (mFramesPerPacket & 0xff);
00099
00100
00101 retBuff[24] = 0;
00102 retBuff[25] = 0;
00103 retBuff[26] = 0;
00104 retBuff[27] = 0;
00105
00106 *outBuff = retBuff;
00107 *outHeaderSize = MAIN_HEADER_SIZE;
00108
00109 return true;
00110
00111 }
00112 bool OggRawAudioInserterInputPin::makeCommentHeader(unsigned char** outBuff, unsigned long* outHeaderSize)
00113 {
00114 char* locVendor = "oggcodecs testbuild";
00115 unsigned long locVendorLength = strlen(locVendor);
00116 unsigned long locPacketLength = locVendorLength + 4 + 4 + 1;
00117
00118 unsigned char* retBuff = new unsigned char[locPacketLength];
00119 iLE_Math::ULongToCharArr(locVendorLength, retBuff);
00120
00121 memcpy((void*)(&retBuff[4]), (const void*)locVendor, locVendorLength);
00122
00123
00124 iLE_Math::ULongToCharArr(0, &retBuff[locVendorLength + 4]);
00125
00126
00127 retBuff[locVendorLength+8] = 1;
00128
00129 *outBuff = retBuff;
00130 *outHeaderSize = locPacketLength;
00131
00132 return true;
00133
00134
00135 }
00136
00137 HRESULT OggRawAudioInserterInputPin::TransformData(unsigned char* inBuf, long inNumBytes)
00138 {
00139
00140 if (!mSentHeaders) {
00141
00142
00143 unsigned char* locHeader = NULL;
00144 unsigned long locHeaderLength = 0;
00145 mFrameByteWidth = (((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.numChannels * ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.bitsPerSample) >> 3;
00146 mBytesPerPacket = mFramesPerPacket * mFrameByteWidth;
00147
00148 makeMainHeader(&locHeader, &locHeaderLength);
00149
00150 sendPacket(locHeader, locHeaderLength, true);
00151
00152 delete[] locHeader;
00153 locHeader = NULL;
00154 locHeaderLength = 0;
00155
00156 makeCommentHeader(&locHeader, &locHeaderLength);
00157
00158 sendPacket(locHeader, locHeaderLength, true);
00159 delete[] locHeader;
00160
00161 mSentHeaders = true;
00162 }
00163
00164
00165 memcpy((void*)&mWorkingBuffer[mNumBufferedBytes], (const void*)inBuf, inNumBytes);
00166 mNumBufferedBytes+=inNumBytes;
00167
00168
00169 unsigned long locBuffersWorth = mNumBufferedBytes / mBytesPerPacket;
00170
00171 for (int i = 0; i < locBuffersWorth; i++) {
00172 sendPacket(&mWorkingBuffer[i*mBytesPerPacket], mBytesPerPacket, false);
00173 }
00174
00175 unsigned long locLeftovers = mNumBufferedBytes % mBytesPerPacket;
00176
00177
00178
00179
00180
00181
00182 sendPacket(&mWorkingBuffer[locBuffersWorth*mBytesPerPacket], locLeftovers, false);
00183
00184
00185 mNumBufferedBytes = 0;
00186
00187 return S_OK;
00188 }
00189
00190 HRESULT OggRawAudioInserterInputPin::sendPacket(unsigned char* inPacketData, unsigned long inNumBytes, bool inIsHeader)
00191 {
00192 if (inIsHeader) {
00193 mUptoFrame = 0;
00194
00195 }
00196 IMediaSample* locSample;
00197 REFERENCE_TIME locFrameStart = 0;
00198 REFERENCE_TIME locFrameEnd = 0;
00199 HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, NULL);
00200
00201 if (FAILED(locHR)) {
00202 return locHR;
00203 }
00204
00205 BYTE* locBuffer = NULL;
00206
00207
00208 locSample->GetPointer(&locBuffer);
00209
00210
00211 if (locSample->GetSize() >= inNumBytes) {
00212
00213 memcpy((void*)locBuffer, (const void*)inPacketData, inNumBytes);
00214 locSample->SetActualDataLength(inNumBytes);
00215
00216 if (!inIsHeader) {
00217
00218 locFrameStart = mUptoFrame;
00219 mUptoFrame += (inNumBytes / mFrameByteWidth);
00220
00221 locFrameEnd = mUptoFrame;
00222
00223 } else {
00224 locFrameStart = 0;
00225 locFrameEnd = 0;
00226
00227 }
00228 locSample->SetMediaTime(&locFrameStart, &locFrameEnd);
00229 locSample->SetTime(&locFrameStart, &locFrameEnd);
00230
00231 locSample->SetSyncPoint(TRUE);
00232
00233
00234 {
00235 CAutoLock locLock(m_pLock);
00236
00237
00238 HRESULT locHR = ((OggRawAudioInserterOutputPin*)(mOutputPin))->mDataQueue->Receive(locSample);
00239 if (locHR != S_OK) {
00240 return locHR;
00241 } else {
00242
00243 return S_OK;
00244 }
00245 }
00246 } else {
00247 throw 0;
00248 }
00249
00250 }
00251 bool OggRawAudioInserterInputPin::ConstructCodec() {
00252
00253 return true;
00254
00255 }
00256 void OggRawAudioInserterInputPin::DestroyCodec() {
00257
00258 }
00259
00260
00261
00262
00263 HRESULT OggRawAudioInserterInputPin::SetMediaType(const CMediaType* inMediaType)
00264 {
00265
00266 if ( (inMediaType->subtype == MEDIASUBTYPE_PCM) &&
00267 (inMediaType->formattype == FORMAT_WaveFormatEx)) {
00268
00269 WAVEFORMATEX* locWaveFormat = (WAVEFORMATEX*)inMediaType->pbFormat;
00270
00271 mFramesPerPacket = 1024;
00272
00273
00274 ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.numHeaders = 2;
00275 ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.samplesPerSec = locWaveFormat->nSamplesPerSec;
00276 ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.numChannels = locWaveFormat->nChannels;
00277 ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.bitsPerSample = locWaveFormat->wBitsPerSample;
00278 ((OggRawAudioInserterFilter*)mParentFilter)->mOggRawAudioFormatBlock.maxFramesPerPacket = 1024;
00279
00280
00281 } else {
00282
00283 throw 0;
00284 }
00285
00286
00287
00288 ConstructCodec();
00289
00290 return CBaseInputPin::SetMediaType(inMediaType);
00291
00292
00293
00294 }