DiracDecodeSourceFilter.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 #include "stdafx.h"
00032 #include ".\DiracDecodeSourceFilter.h"
00033 
00034 CFactoryTemplate g_Templates[] = 
00035 {
00036     { 
00037                 L"DiracDecodeSourceFilter",                                             // Name
00038             &CLSID_DiracDecodeSourceFilter,            // CLSID
00039             DiracDecodeSourceFilter::CreateInstance,    // Method to create an instance of MyComponent
00040         NULL,                                                                   // Initialization function
00041         NULL                                                                    // Set-up information (for filters)
00042     }
00043 
00044 };
00045 
00046 // Generic way of determining the number of items in the template
00047 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
00048 
00049 
00050 CUnknown* WINAPI DiracDecodeSourceFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr) 
00051 {
00052         DiracDecodeSourceFilter *pNewObject = new DiracDecodeSourceFilter();
00053     if (pNewObject == NULL) {
00054         *pHr = E_OUTOFMEMORY;
00055     }
00056     return pNewObject;
00057 } 
00058 
00059 DiracDecodeSourceFilter::DiracDecodeSourceFilter(void)
00060         :       CBaseFilter(NAME("DiracDecodeSourceFilter"), NULL, m_pLock, CLSID_DiracDecodeSourceFilter)
00061         ,       mDecoder(NULL)
00062 {
00063         mDiracSourcePin = new DiracDecodeSourcePin(this, m_pLock);
00064 }
00065 
00066 DiracDecodeSourceFilter::~DiracDecodeSourceFilter(void)
00067 {
00068         delete mDiracSourcePin;
00069         mDiracSourcePin = NULL;
00070 }
00071 
00072 //BaseFilter Interface
00073 int DiracDecodeSourceFilter::GetPinCount() {
00074         return 1;
00075 }
00076 CBasePin* DiracDecodeSourceFilter::GetPin(int inPinNo) {
00077 
00078         if (inPinNo == 0) {
00079                 return mDiracSourcePin;
00080         } else {
00081                 return NULL;
00082         }
00083 }
00084 
00085 //IAMFilterMiscFlags Interface
00086 ULONG DiracDecodeSourceFilter::GetMiscFlags(void) {
00087         return AM_FILTER_MISC_FLAGS_IS_SOURCE;
00088 }
00089 
00090         //IFileSource Interface
00091 STDMETHODIMP DiracDecodeSourceFilter::GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType) {
00092         //Return the filename and mediatype of the raw data
00093 
00094          
00095         LPOLESTR x = SysAllocString(mFileName.c_str());
00096         *outFileName = x;
00097         
00098         return S_OK;
00099 }
00100 
00101 //ANX::: Seek table will need modifying to handle this.
00102 STDMETHODIMP DiracDecodeSourceFilter::Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType) {
00103         //Initialise the file here and setup all the streams
00104         CAutoLock locLock(m_pLock);
00105         mFileName = inFileName;
00106 
00107         //Strip the extension...
00108         //size_t locDotPos = mFileName.find_last_of('.');
00109         //if (locDotPos != ios_base::npos) {
00110         //      mHDRFileName = mFileName.substr(0, locDotPos);
00111         //      mHDRFileName += ".hdr";
00112         //} else {
00113         //      return S_FALSE;
00114         //}
00115 
00116         mInputFile.open(StringHelper::toNarrowStr(mFileName), ios_base::in | ios_base::binary);
00117 
00118         if (!mInputFile.is_open()) {
00119                 return S_FALSE;
00120         }
00121 
00122 
00123         
00124         return S_OK;
00125 }
00126 
00127 STDMETHODIMP DiracDecodeSourceFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00128 {
00129 
00130         return CBaseFilter::NonDelegatingQueryInterface(riid, ppv); 
00131 }
00132 
00133 
00134 //IMEdiaStreaming
00135 STDMETHODIMP DiracDecodeSourceFilter::Run(REFERENCE_TIME tStart) {
00136         const REFERENCE_TIME A_LONG_TIME = UNITS * 1000;
00137         CAutoLock locLock(m_pLock);
00138         //debugLog<<"Run  :  time = "<<tStart<<endl;
00139         //DeliverNewSegment(tStart, tStart + A_LONG_TIME, 1.0);
00140         return CBaseFilter::Run(tStart);
00141         
00142 
00143 }
00144 STDMETHODIMP DiracDecodeSourceFilter::Pause(void) {
00145         CAutoLock locLock(m_pLock);
00146         //debugLog << "** Pause called **"<<endl;
00147         if (m_State == State_Stopped) {
00148                 //debugLog << "Was in stopped state... starting thread"<<endl;
00149                 if (ThreadExists() == FALSE) {
00150                         Create();
00151                 }
00152                 CallWorker(THREAD_RUN);
00153         }
00154         //debugLog<<"Was NOT is stopped state, not doing much at all..."<<endl;
00155         
00156         HRESULT locHR = CBaseFilter::Pause();
00157         
00158         return locHR;
00159         
00160 }
00161 STDMETHODIMP DiracDecodeSourceFilter::Stop(void) {
00162         CAutoLock locLock(m_pLock);
00163         //debugLog<<"** Stop Called ** "<<endl;
00164         CallWorker(THREAD_EXIT);
00165         Close();
00166         //DeliverBeginFlush();
00167         //DeliverEndFlush();
00168         return CBaseFilter::Stop();
00169 }
00170 
00171 HRESULT DiracDecodeSourceFilter::DataProcessLoop() {
00172 
00173     do 
00174     {
00175         /* parse the input data */
00176         state = dirac_parse(decoder);
00177         
00178         switch (state)
00179         {
00180         case STATE_BUFFER:
00181             /*
00182             * parser is out of data. Read data from input stream and pass it
00183             * on to the parser
00184             */
00185             bytes = fread (buffer, 1, sizeof(buffer), ifp);
00186             if (bytes)
00187                 dirac_buffer (decoder, buffer, buffer + bytes);
00188             break;
00189 
00190         case STATE_SEQUENCE:
00191             {
00192             /*
00193             * Start of sequence detected. Allocate for the frame buffers and
00194             * pass this buffer to the parser
00195             */
00196             unsigned char *buf[3];
00197 
00198             if (verbose)
00199             {
00200                 fprintf (stderr, "SEQUENCE : width=%d height=%d chroma=%s chroma_width=%d chroma_height=%d num_frames=%d frame_rate=%d, interlace=%s topfieldfirst=%s\n", 
00201                 decoder->seq_params.width,
00202                 decoder->seq_params.height,
00203                 chroma2string(decoder->seq_params.chroma),
00204                 decoder->seq_params.chroma_width,
00205                 decoder->seq_params.chroma_height,
00206                 decoder->seq_params.num_frames,
00207                 decoder->seq_params.frame_rate,
00208                 decoder->seq_params.interlace ? "yes" : "no",
00209                 decoder->seq_params.interlace ? "yes" : "no");
00210             }
00211 
00212             FreeFrameBuffer(decoder);
00213 
00214             buf[0] = buf[1] = buf[2] = 0;
00215 
00216             buf[0] = (unsigned char *)malloc (decoder->seq_params.width * decoder->seq_params.height);
00217             if (decoder->seq_params.chroma != Yonly)
00218             {
00219                 buf[1] = (unsigned char *)malloc (decoder->seq_params.chroma_width * decoder->seq_params.chroma_height);
00220                 buf[2] = (unsigned char *)malloc (decoder->seq_params.chroma_width * decoder->seq_params.chroma_height);
00221             }
00222             dirac_set_buf (decoder, buf, NULL);
00223 
00224             /* write the header file */
00225             WritePicHeader(decoder, fphdr);
00226             }
00227             break;
00228 
00229         case STATE_SEQUENCE_END:
00230             /*
00231             * End of Sequence detected. Free the frame buffers
00232             */
00233             if (verbose)
00234                 fprintf (stderr, "SEQUENCE_END\n");
00235             
00236             FreeFrameBuffer(decoder);
00237             break;
00238         
00239         case STATE_PICTURE_START:
00240             /*
00241             * Start of frame detected. If decoder is too slow and frame can be
00242             * skipped, inform the parser to skip decoding the frame
00243             */
00244             num_frames++;
00245             if (verbose)
00246             {
00247                 fprintf (stderr, "PICTURE_START : frame_type=%s frame_num=%d\n",
00248                     ftype2string(decoder->frame_params.ftype),
00249                     decoder->frame_params.fnum);
00250             }
00251             /* Just for testing skip every L2_frame */
00252             if (skip && decoder->frame_params.ftype == L2_frame)
00253             {
00254                 if (verbose)
00255                     fprintf (stderr, "              : Skipping frame\n");
00256 
00257                 dirac_skip (decoder, 1);
00258             }
00259             else
00260                 dirac_skip (decoder, 0);
00261             break;
00262 
00263         case STATE_PICTURE_AVAIL:
00264             if (verbose)
00265             {
00266                 fprintf (stderr, "PICTURE_AVAIL : frame_type=%s frame_num=%d\n",
00267                     ftype2string(decoder->frame_params.ftype),
00268                     decoder->frame_params.fnum);
00269             }
00270             /* picture available for display */
00271             WritePicData(decoder, fpdata);
00272             break;
00273 
00274         case STATE_INVALID:
00275             /* Invalid state. Stop all processing */
00276             fprintf (stderr, "Error processing file %s\n", iname);
00277             break;
00278 
00279         default:
00280             continue;
00281         }
00282     } while (bytes > 0 && state != STATE_INVALID);
00283 
00284 
00285 
00286 
00287 
00288         return S_OK;
00289 }
00290 
00291 //CAMThread Stuff
00292 DWORD DiracDecodeSourceFilter::ThreadProc(void) {
00293         //debugLog << "Thread Proc Called..."<<endl;
00294         while(true) {
00295                 DWORD locThreadCommand = GetRequest();
00296                 //debugLog << "Command = "<<locThreadCommand<<endl;
00297                 switch(locThreadCommand) {
00298                         case THREAD_EXIT:
00299                                 //debugLog << "EXIT ** "<<endl;
00300                                 Reply(S_OK);
00301                                 return S_OK;
00302 
00303                         //case THREAD_PAUSE:
00304                         //      // we are paused already
00305                         //      Reply(S_OK);
00306                         //      break;
00307 
00308                         case THREAD_RUN:
00309                                 //debugLog << "RUN ** "<<endl;
00310                                 Reply(S_OK);
00311                                 DataProcessLoop();
00312                                 break;
00313                 }
00314         
00315         
00316         }
00317         return S_OK;
00318 }

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