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 "CMMLDecodeInputPin.h"
00034 #include "CMMLDecodeFilter.h"
00035
00036 CMMLDecodeInputPin::CMMLDecodeInputPin(CMMLDecodeFilter* inParentFilter, HRESULT* outHR)
00037 : CTransformInputPin(NAME("CMMLDecodeInputPin"), inParentFilter, outHR, L"CMML In")
00038 , mSetupState(VSS_SEEN_NOTHING)
00039 , mCMMLFormatBlock(NULL)
00040 , mCMMLHeadPacket(NULL)
00041 {
00042
00043 }
00044
00045 CMMLDecodeInputPin::~CMMLDecodeInputPin(void)
00046 {
00047 delete mCMMLFormatBlock;
00048 delete mCMMLHeadPacket;
00049 }
00050
00051 STDMETHODIMP CMMLDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00052 {
00053 if (riid == IID_IMediaSeeking) {
00054 *ppv = (IMediaSeeking*)this;
00055 ((IUnknown*)*ppv)->AddRef();
00056 return NOERROR;
00057 } else if (riid == IID_IOggDecoder) {
00058 *ppv = (IOggDecoder*)this;
00059
00060 return NOERROR;
00061
00062 }
00063
00064 return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv);
00065 }
00066
00067 HRESULT CMMLDecodeInputPin::SetMediaType(const CMediaType* inMediaType)
00068 {
00069
00070
00071 if (CheckMediaType(inMediaType) == S_OK) {
00072
00073
00074 } else {
00075 throw 0;
00076 }
00077 return CBaseInputPin::SetMediaType(inMediaType);
00078
00079 }
00080
00081 HRESULT CMMLDecodeInputPin::CheckMediaType(const CMediaType *inMediaType)
00082 {
00083 if ( (inMediaType->majortype == MEDIATYPE_OggPacketStream)
00084 && (inMediaType->subtype == MEDIASUBTYPE_None)
00085 && (inMediaType->formattype == FORMAT_OggIdentHeader)) {
00086 if (inMediaType->cbFormat == CMML_IDENT_HEADER_SIZE) {
00087 if (strncmp((char*)inMediaType->pbFormat, "CMML\000\000\000\000", 8) == 0) {
00088
00089 return S_OK;
00090 }
00091 }
00092 }
00093 return S_FALSE;
00094
00095 }
00096 HRESULT CMMLDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
00097 {
00098 outRequestedProps->cbBuffer = CMML_BUFFER_SIZE;
00099 outRequestedProps->cBuffers = CMML_NUM_BUFFERS;
00100 outRequestedProps->cbAlign = 1;
00101 outRequestedProps->cbPrefix = 0;
00102
00103 return S_OK;
00104 }
00105 LOOG_INT64 CMMLDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
00106 {
00107
00108 LOOG_INT64 locMask = 0xffffffffffffffff >> (64 - mCMMLFormatBlock->granuleSplitBits);
00109 LOOG_INT64 locTime = ((inGranule & locMask) + (inGranule >> mCMMLFormatBlock->granuleSplitBits));
00110
00111 return ((locTime * mCMMLFormatBlock->granuleDenominator * UNITS) / mCMMLFormatBlock->granuleNumerator);
00112 }
00113
00114 LOOG_INT64 CMMLDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
00115 {
00116
00117 return inGranule;
00118 }
00119 IOggDecoder::eAcceptHeaderResult CMMLDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
00120 {
00121 switch (mSetupState) {
00122 case VSS_SEEN_NOTHING:
00123 if (strncmp((char*)inCodecHeaderPacket->packetData(), "CMML\000\000\000\000", 0) == 0) {
00124 handleHeaderPacket(inCodecHeaderPacket);
00125 mSetupState = VSS_SEEN_BOS;
00126 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00127 }
00128 mSetupState = VSS_ERROR;
00129 return IOggDecoder::AHR_INVALID_HEADER;
00130
00131 case VSS_SEEN_BOS:
00132 if (strncmp((char*)inCodecHeaderPacket->packetData(), "<?xml", 5) == 0) {
00133 mSetupState = VSS_SEEN_XML_HEADER;
00134
00135 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00136 }
00137 return IOggDecoder::AHR_INVALID_HEADER;
00138
00139 case VSS_SEEN_XML_HEADER:
00140 if (strncmp((char*)inCodecHeaderPacket->packetData(), "<head", 5) == 0) {
00141 mSetupState = VSS_ALL_HEADERS_SEEN;
00142
00143 mCMMLHeadPacket = inCodecHeaderPacket->clone();
00144 return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
00145 }
00146 return IOggDecoder::AHR_INVALID_HEADER;
00147 case VSS_ALL_HEADERS_SEEN:
00148 case VSS_ERROR:
00149 default:
00150 return IOggDecoder::AHR_UNEXPECTED;
00151 }
00152 }
00153
00154
00155
00156 bool CMMLDecodeInputPin::handleHeaderPacket(OggPacket* inHeaderPack)
00157 {
00158 delete mCMMLFormatBlock;
00159 mCMMLFormatBlock = new sCMMLFormatBlock;
00160 mCMMLFormatBlock->granuleNumerator = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 12);
00161 mCMMLFormatBlock->granuleDenominator = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 20);
00162 mCMMLFormatBlock->granuleSplitBits = inHeaderPack->packetData()[28];
00163 return true;
00164
00165
00166
00167
00168 }
00169 string CMMLDecodeInputPin::getCodecShortName()
00170 {
00171 return "CMML";
00172 }
00173 string CMMLDecodeInputPin::getCodecIdentString()
00174 {
00175
00176 return "CMML";
00177 }
00178