TheoraEncodeFilter.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 "Theoraencodefilter.h"
00034 
00035 
00036 //COM Factory Template
00037 CFactoryTemplate g_Templates[] = 
00038 {
00039     { 
00040                 L"Theora Encode Filter",                                                // Name
00041             &CLSID_TheoraEncodeFilter,            // CLSID
00042             TheoraEncodeFilter::CreateInstance, // Method to create an instance of MyComponent
00043         NULL,                                                                   // Initialization function
00044         NULL                                                                    // Set-up information (for filters)
00045     },
00046     { 
00047                 L"Theora Encode Properties",                                            // Name
00048             &CLSID_PropsTheoraEncoder,            // CLSID
00049             PropsTheoraEncoder::CreateInstance, // Method to create an instance of MyComponent
00050         NULL,                                                                   // Initialization function
00051         NULL                                                                    // Set-up information (for filters)
00052     }
00053 
00054 
00055 };
00056 
00057 // Generic way of determining the number of items in the template
00058 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
00059 
00060 CUnknown* WINAPI TheoraEncodeFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00061 {
00062         //This routine is the COM implementation to create a new Filter
00063         TheoraEncodeFilter *pNewObject = new TheoraEncodeFilter();
00064     if (pNewObject == NULL) {
00065         *pHr = E_OUTOFMEMORY;
00066     }
00067         return pNewObject;
00068 } 
00069 STDMETHODIMP TheoraEncodeFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00070         if (riid == IID_ITheoraEncodeSettings) {
00071                 *ppv = (ITheoraEncodeSettings*)this;
00072                 ((IUnknown*)*ppv)->AddRef();
00073                 return NOERROR;
00074         } else if (riid == IID_ISpecifyPropertyPages) {
00075                 *ppv = (ISpecifyPropertyPages*)this;
00076                 ((IUnknown*)*ppv)->AddRef();
00077                 return NOERROR;
00078         }
00079 
00080 
00081         return AbstractTransformFilter::NonDelegatingQueryInterface(riid, ppv);
00082 }
00083 
00084 TheoraEncodeFilter::TheoraEncodeFilter(void)
00085         :       AbstractTransformFilter(NAME("Theora Encoder"), CLSID_TheoraEncodeFilter)
00086 {
00087         bool locWasConstructed = ConstructPins();
00088 }
00089 
00090 TheoraEncodeFilter::~TheoraEncodeFilter(void)
00091 {
00092 }
00093 
00094 bool TheoraEncodeFilter::ConstructPins() 
00095 {
00096 
00097 
00098         //Inputs Video / Varios / VideoInfoHeader
00099         //Outputs Video / Theora / THeora
00100 
00101         //Vector to hold our set of media types we want to accept.
00102         vector<CMediaType*> locAcceptableTypes;
00103 
00104         //Setup the media types for the output pin.
00105         CMediaType* locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);              //Deleted in pin destructor
00106         locAcceptMediaType->subtype = MEDIASUBTYPE_Theora;
00107         locAcceptMediaType->formattype = FORMAT_Theora;
00108         
00109         locAcceptableTypes.push_back(locAcceptMediaType);
00110 
00111         //Output pin must be done first because it's passed to the input pin.
00112         mOutputPin = new TheoraEncodeOutputPin(this, m_pLock, locAcceptableTypes);                      //Deleted in base class destructor
00113 
00114         //Clear out the vector, now we've already passed it to the output pin.
00115         locAcceptableTypes.clear();
00116 
00117         //Setup the media Types for the input pin.
00118         locAcceptMediaType = NULL;
00119 
00120         //YV12
00121         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00122         locAcceptMediaType->subtype = MEDIASUBTYPE_YV12;
00123         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00124 
00125         locAcceptableTypes.push_back(locAcceptMediaType);
00126 
00127         //YUY2
00128         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00129         locAcceptMediaType->subtype = MEDIASUBTYPE_YUY2;
00130         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00131 
00132         locAcceptableTypes.push_back(locAcceptMediaType);
00133 
00134         //AYUV
00135         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00136         locAcceptMediaType->subtype = MEDIASUBTYPE_AYUV;
00137         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00138 
00139         locAcceptableTypes.push_back(locAcceptMediaType);
00140 
00141         //RGB24
00142         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00143         locAcceptMediaType->subtype = MEDIASUBTYPE_RGB24;
00144         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00145 
00146         locAcceptableTypes.push_back(locAcceptMediaType);
00147 
00148         //RGB32
00149         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00150         locAcceptMediaType->subtype = MEDIASUBTYPE_RGB32;
00151         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00152 
00153         locAcceptableTypes.push_back(locAcceptMediaType);
00154 
00155         //UYVY
00156         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00157         locAcceptMediaType->subtype = MEDIASUBTYPE_UYVY;
00158         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00159 
00160         locAcceptableTypes.push_back(locAcceptMediaType);
00161 
00162         //YVYU
00163         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00164         locAcceptMediaType->subtype = MEDIASUBTYPE_YVYU;
00165         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00166 
00167         locAcceptableTypes.push_back(locAcceptMediaType);
00168 
00169         //IYUV
00170         locAcceptMediaType = new CMediaType(&MEDIATYPE_Video);                  //Deleted by pin
00171         locAcceptMediaType->subtype = MEDIASUBTYPE_IYUV;
00172         locAcceptMediaType->formattype = FORMAT_VideoInfo;
00173 
00174         locAcceptableTypes.push_back(locAcceptMediaType);
00175         
00176         mInputPin = new TheoraEncodeInputPin(this, m_pLock, mOutputPin, locAcceptableTypes);    //Deleted in base class filter destructor.
00177         return true;
00178 }
00179 
00180 //Implementation of ITheoraEncodeSEttings
00181 STDMETHODIMP_(unsigned long) TheoraEncodeFilter::targetBitrate() {
00182         return ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->target_bitrate;
00183 }
00184 STDMETHODIMP_(unsigned char) TheoraEncodeFilter::quality() {
00185         return ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->quality;
00186 }
00187 STDMETHODIMP_(unsigned long) TheoraEncodeFilter::keyframeFreq() {
00188         return ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->keyframe_frequency;
00189 }
00190 
00191 STDMETHODIMP_(bool) TheoraEncodeFilter::setTargetBitrate(unsigned long inBitrate) {
00192         //Needs error checking
00193         ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->target_bitrate = inBitrate;
00194         ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->keyframe_data_target_bitrate = (inBitrate * 3)/2;
00195         //mTheoraFormatBlock.targetBitrate = inBitrate;
00196         //mTheoraFormatBlock.
00197         return true;
00198 
00199 }
00200 STDMETHODIMP_(bool) TheoraEncodeFilter::setQuality(unsigned char inQuality) {
00201         //Needs error checking
00202         
00203         ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->quality = inQuality;
00204         return true;
00205 }
00206 STDMETHODIMP_(bool) TheoraEncodeFilter::setKeyframeFreq(unsigned long inKeyframeFreq) {
00207         //Needs error checking
00208         ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->keyframe_frequency = inKeyframeFreq;
00209         ((TheoraEncodeInputPin*)mInputPin)->theoraInfo()->keyframe_frequency_force = inKeyframeFreq;
00210         //NOTE: If you ever change it so that _force can be higher... you must use the maximum.
00211         mTheoraFormatBlock.maxKeyframeInterval = PropsTheoraEncoder::log2(inKeyframeFreq);
00212         return true;
00213 }
00214 
00215 //SpecifyPropertyPages Implementation
00216 STDMETHODIMP TheoraEncodeFilter::GetPages(CAUUID* outPropPages) {
00217         if (outPropPages == NULL) return E_POINTER;
00218 
00219         const int NUM_PROP_PAGES = 1;
00220     outPropPages->cElems = NUM_PROP_PAGES;
00221     outPropPages->pElems = (GUID*)(CoTaskMemAlloc(sizeof(GUID) * NUM_PROP_PAGES));
00222     if (outPropPages->pElems == NULL) 
00223     {
00224         return E_OUTOFMEMORY;
00225     }
00226 
00227         outPropPages->pElems[0] = CLSID_PropsTheoraEncoder;
00228     
00229     return S_OK;
00230 
00231 }

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