DiracEncodeInputPin.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 "diracencodeinputpin.h"
00034 
00035 DiracEncodeInputPin::DiracEncodeInputPin(AbstractVideoEncodeFilter* inParentFilter, CCritSec* inFilterLock, AbstractVideoEncodeOutputPin* inOutputPin)
00036         :       AbstractVideoEncodeInputPin(inParentFilter, inFilterLock, inOutputPin, NAME("DiracEncodeInputPin"), L"YV12 In")
00037         ,       mXOffset(0)
00038         ,       mYOffset(0)
00039         
00040 
00041 {
00042         //debugLog.open("g:\\logs\\theoencfiltinput.log", ios_base::out);
00043 
00044         
00045 }
00046 
00047 DiracEncodeInputPin::~DiracEncodeInputPin(void)
00048 {
00049         //debugLog.close();
00050         DestroyCodec();
00051 
00052 
00053 }
00054 
00055 
00056 HRESULT DiracEncodeInputPin::deliverData(LONGLONG inStart, LONGLONG inEnd, unsigned char* inBuf, unsigned long inNumBytes) {
00057         //debugLog <<" deliverData : "<<inStart<<" - "<<inEnd<<"  :: size = "<<inNumBytes<<endl;
00058         //Get a pointer to a new sample stamped with our time
00059         IMediaSample* locSample;
00060         HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, &inStart, &inEnd, NULL);
00061 
00062         if (locHR != S_OK) {
00063                 //We get here when the application goes into stop mode usually.
00064                 return locHR;
00065         }       
00066         
00067         BYTE* locBuffer = NULL;
00068 
00069         
00070         //Make our pointers set to point to the samples buffer
00071         locSample->GetPointer(&locBuffer);
00072 
00073         if (locSample->GetSize() >= inNumBytes) {
00074 
00075                 memcpy((void*)locBuffer, (const void*)inBuf, inNumBytes);
00076                 
00077                 //Set the sample parameters.
00078                 SetSampleParams(locSample, inNumBytes, &inStart, &inEnd);
00079 
00080                 {
00081                         CAutoLock locLock(m_pLock);
00082 
00083                         HRESULT locHR = mOutputPin->mDataQueue->Receive(locSample);                                             //->DownstreamFilter()->Receive(locSample);
00084                         if (locHR != S_OK) {
00085                                 return locHR;   
00086                         } else {
00087                         }
00088                 }
00089                 //debugLog<<"deliverData : SUCCESS"<<endl;
00090                 return S_OK;
00091         } else {
00092                 //debugLog<<"Buffer too small !!!! FATALITY !"<<endl;
00093                 throw 0;
00094         }
00095 
00096 }
00097 
00098 long DiracEncodeInputPin::encodeYV12ToYV12(unsigned char* inBuf, long inNumBytes) {
00100 
00109 
00110 
00120 
00124         //
00128 
00131 
00132 
00134         //unsigned char* locSourceUptoPtr = inBuf;  //View only... don't delete locUptoPtr
00136         //
00140 
00142         //char* locDestUptoPtr = mYUV.y;
00144 
00146         //if (mYOffset != 0) {
00147         //      memset((void*)locDestUptoPtr, NULL, mYOffset * mYUV.y_width);                   //Is it needed to zero this out ? Or just leave junk ?
00148         //      locDestUptoPtr += (mYOffset * mYUV.y_width);
00149         //}
00152 
00154         //if (mXOffset == 0) {
00155         //      //Slight optimisation to keep the inner loop tighter
00156         //      for (long line = 0; line < mHeight; line++) {
00157         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth);
00158         //              locSourceUptoPtr += mWidth;
00159         //              locDestUptoPtr += mWidth;
00160         //      }
00161         //} else {
00162         //      for (long line = 0; line < mHeight; line++) {
00163         //              //Pad the start of the line with mXOffset bytes
00164         //              memset((void*)locDestUptoPtr, NULL, mXOffset);
00165         //              locDestUptoPtr += mXOffset;
00166 
00167         //              //Fill in the meaty bit
00168         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth);
00169         //              locSourceUptoPtr += mWidth;
00170         //              locDestUptoPtr += mWidth;
00171 
00172         //              //Pad the end of the line with mXOffset bytes
00173         //              memset((void*)locDestUptoPtr, NULL, mXOffset);
00174         //              locDestUptoPtr += mXOffset;
00175         //      }
00176 
00177         //}
00178 
00180         //if (mYOffset != 0) {
00181         //      memset((void*)locDestUptoPtr, NULL, mYOffset * mYUV.y_width);                   //Is it needed to zero this out ? Or just leave junk ?
00182         //      locDestUptoPtr += (mYOffset * mYUV.y_width);
00183         //      //Source pointer does not advance
00184         //}
00185         //
00186 
00187 
00191 
00193         //locDestUptoPtr = mYUV.v;
00195 
00197         //if (mYOffset != 0) {
00198         //      memset((void*)locDestUptoPtr, NULL, (mYOffset * mYUV.uv_width) / 2);                    //Is it needed to zero this out ? Or just leave junk ?
00199         //      locDestUptoPtr += ((mYOffset * mYUV.uv_width) / 2);
00200         //      //Source pointer does not advance
00201         //}
00203 
00205         //if (mXOffset == 0) {
00206         //      //Slight optimisation to keep the inner loop tighter
00207         //      for (long line = 0; line < mHeight / 2; line++) {
00208         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth / 2);
00209         //              locSourceUptoPtr += (mWidth / 2);
00210         //              locDestUptoPtr += (mWidth / 2);
00211         //      }
00212         //} else {
00213         //      for (long line = 0; line < mHeight / 2; line++) {
00214         //              //Pad the start of the line
00215         //              memset((void*)locDestUptoPtr, NULL, mXOffset / 2);
00216         //              locDestUptoPtr += (mXOffset / 2);
00217         //              //Source pointer does not advance
00218 
00219         //              //Fill in the meaty bit
00220         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth / 2);
00221         //              locSourceUptoPtr += (mWidth / 2);
00222         //              locDestUptoPtr += (mWidth / 2);
00223 
00224         //              //Pad the end of the line
00225         //              memset((void*)locDestUptoPtr, NULL, mXOffset / 2);
00226         //              locDestUptoPtr += (mXOffset / 2);
00227         //              //Source pointer does not advance
00228         //      }
00229 
00230         //}
00231 
00233         //if (mYOffset != 0) {
00234         //      memset((void*)locDestUptoPtr, NULL, (mYOffset * mYUV.uv_width) / 2);                    //Is it needed to zero this out ? Or just leave junk ?
00235         //      locDestUptoPtr += ((mYOffset * mYUV.uv_width) / 2);
00236         //      //Source pointer does not advance
00237         //}
00238         //
00239 
00240 
00241 
00242 
00246 
00248         //locDestUptoPtr = mYUV.u;
00250 
00252         //if (mYOffset != 0) {
00253         //      memset((void*)locDestUptoPtr, NULL, (mYOffset * mYUV.uv_width) / 2);                    //Is it needed to zero this out ? Or just leave junk ?
00254         //      locDestUptoPtr += ((mYOffset * mYUV.uv_width) / 2);
00255         //      //Source pointer does not advance
00256         //}
00258 
00260         //if (mXOffset == 0) {
00261         //      //Slight optimisation to keep the inner loop tighter
00262         //      for (long line = 0; line < mHeight / 2; line++) {
00263         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth / 2);
00264         //              locSourceUptoPtr += (mWidth / 2);
00265         //              locDestUptoPtr += (mWidth / 2);
00266         //      }
00267         //} else {
00268         //      for (long line = 0; line < mHeight / 2; line++) {
00269         //              //Pad the start of the line
00270         //              memset((void*)locDestUptoPtr, NULL, mXOffset / 2);
00271         //              locDestUptoPtr += (mXOffset / 2);
00272         //              //Source pointer does not advance
00273 
00274         //              //Fill in the meaty bit
00275         //              memcpy((void*)locDestUptoPtr, (const void*)locSourceUptoPtr, mWidth / 2);
00276         //              locSourceUptoPtr += (mWidth / 2);
00277         //              locDestUptoPtr += (mWidth / 2);
00278 
00279         //              //Pad the end of the line
00280         //              memset((void*)locDestUptoPtr, NULL, mXOffset / 2);
00281         //              locDestUptoPtr += (mXOffset / 2);
00282         //              //Source pointer does not advance
00283         //      }
00284 
00285         //}
00286 
00288         //if (mYOffset != 0) {
00289         //      memset((void*)locDestUptoPtr, NULL, (mYOffset * mYUV.uv_width) / 2);                    //Is it needed to zero this out ? Or just leave junk ?
00290         //      locDestUptoPtr += ((mYOffset * mYUV.uv_width) / 2);
00291         //      //Source pointer does not advance
00292         //}
00293 
00295         return 0;
00296 
00297 }
00298 
00299 //-------------------------------------------------------------------------
00300 
00301 
00302 
00303 
00304 
00305 //PURE VIRTUALS
00306 long DiracEncodeInputPin::encodeData(unsigned char* inBuf, long inNumBytes) {
00307 
00308         //TODO::: Break this function up a bit !!
00309 
00310         //Time stamps are granule pos not directshow times
00311         //debugLog<<"Encode data"<<endl;
00312 
00313 
00314         LONGLONG locFrameStart = mUptoFrame;
00315         LONGLONG locFrameEnd = 0;
00316         HRESULT locHR = S_OK;
00317         if (!mBegun) {
00318                 //debugLog<<"encodeData : First time"<<endl;
00319                 //mBegun = true;
00320                 //
00321                 //StampedOggPacket** locHeaders;
00322                 //locHeaders = mTheoraEncoder.initCodec(mTheoraInfo);
00323 
00324                 //for (int i = 0; i < 3; i++) {
00325                 //      locHR = deliverData(0,0,locHeaders[i]->packetData(), locHeaders[i]->packetSize());
00326                 //      if (locHR != S_OK) {
00327                 //              return locHR;
00328                 //      }
00329                 //}
00330         }
00331 
00332         if (mPinInputType.subtype == MEDIASUBTYPE_YV12) {
00333                 
00334                 encodeYV12ToYV12(inBuf, inNumBytes);
00335 
00336                 
00337                 
00338                 
00339                 //}     else if (mPinInputType.subtype == MEDIASUBTYPE_AYUV) {
00340         //      encodeAYUVtoYV12(inBuf, inNumBytes);
00341 
00342         //} else if (mPinInputType.subtype == MEDIASUBTYPE_RGB32) {
00343         //      encodeRGB32toYV12(inBuf, inNumBytes);
00344 
00345         //} else if (mPinInputType.subtype == MEDIASUBTYPE_RGB24) {
00346         //      encodeRGB24toYV12(inBuf, inNumBytes);
00347 
00348 
00349         //} else if (mPinInputType.subtype == MEDIASUBTYPE_YV12) {
00350         //      //Should be more specifc.
00351         //      //debugLog<<"About to encode YV12 to YV12"<<endl;
00352         //      encodeYV12ToYV12(inBuf, inNumBytes);
00353         //} else if (mPinInputType.subtype == MEDIASUBTYPE_UYVY) {
00354         //      
00355         //      
00356         //      encodeUYVYToYV12(inBuf, inNumBytes);
00357 
00358         //} else if (mPinInputType.subtype == MEDIASUBTYPE_YVYU) {
00359         //      
00360         //      
00361         //      encodeYVYUToYV12(inBuf, inNumBytes);
00362         //} else if (mPinInputType.subtype == MEDIASUBTYPE_IYUV) {
00363         //      
00364         //      
00365         //      encodeIYUVToYV12(inBuf, inNumBytes);
00366 
00367                 
00368         } else {
00369 
00370                 //FATAL ERROR
00371                 throw 0;
00372         }
00373         
00374 
00375         //StampedOggPacket* locPacket = mTheoraEncoder.encodeTheora(&mYUV);
00376         //if (locPacket == NULL) {
00377         //      //debugLog<<"Encode returns NULL"<<endl;
00378         //      return S_FALSE;
00379         //}
00380         //locFrameEnd           = mUptoFrame 
00381         //                              = locPacket->endTime();
00382         //debugLog<<"Delivering..."<<endl;
00383         
00384         
00385         
00386         
00387         
00388         //return deliverData(locFrameStart, locFrameEnd, locPacket->packetData(), locPacket->packetSize());
00389 
00390 }
00391 bool DiracEncodeInputPin::ConstructCodec() {
00392 
00393         //debugLog<<"Contructing codec..."<<endl;
00394 //      theora_info_init(&mTheoraInfo);
00395         
00396         //Round up to multiple of 16 for theora
00397 
00398         //---------------------------------------------------------------------------------------------------------------
00399         //mTheoraInfo values
00400         //==================
00401         //width, height                                 -       /16 up rounded values
00402         //frame_width, frame_height             -       raw video source values
00403         //offset_x                                              -       CENTRED - *half* the difference between width and frame_width
00404         //offset_y                                              -       CENTRED - *half* the difference between height and frame_heigth
00405 
00406         //mYUV values - for YV12 format
00407         //=============================
00408         //y_width, y_stride                             -       Both equal and equal to the /16 up rounded wdith values
00409         //uv_width, uv_stride                   -       Both equal and equal to *half* the /16 up rounded width values
00410         //y_height                                              -       Equal to the /16 up rounded height value
00411         //uv_height                                             -       Equal to *half* the /16 up rounded height value
00412         //y                                                             -       Buffer of size y_width*y_height (/16 up rounded values)
00413         //u,v                                                   -       Buffers each *quarter* the size of the y buffer (/16 up rounded values)
00414 
00415         //Member data
00416         //===========
00417         //mWidth                                                -       raw video source values... equal to frame_width
00418         //mHeight                                               -       raw video source values... equal to frame_height
00419         //mXOffset                                              -       x offset
00420         //mYOffset                                              -       y offset
00421         //---------------------------------------------------------------------------------------------------------------
00422 
00424         //mTheoraInfo.width                     =       mYUV.y_width
00425         //                                                      =       mYUV.y_stride
00426         //                                                      =       (((mVideoFormat->bmiHeader.biWidth + 15)>>4)<<4);
00427 
00428         //mTheoraInfo.frame_width               =       mWidth
00429         //                                                      =       mVideoFormat->bmiHeader.biWidth;
00430 
00431         //mYUV.uv_width                         =       mYUV.uv_stride
00432         //                                                      =       mYUV.y_width/2;
00433 
00434         //
00436 
00438         //mTheoraInfo.height                    =       mYUV.y_height
00439         //                                                      =       (((mVideoFormat->bmiHeader.biHeight + 15)>>4)<<4);
00440 
00441         //mTheoraInfo.frame_height      =       mHeight
00442         //                                                      =       mVideoFormat->bmiHeader.biHeight;
00443 
00444         //mYUV.uv_height                                =       mYUV.y_height/2;
00445 
00446         //
00448 
00450         //mTheoraInfo.offset_x          =       mXOffset
00451         //                                                      =       (mTheoraInfo.width - mWidth) / 2;
00452 
00453         //mTheoraInfo.offset_y          =       mYOffset
00454         //                                                      =       (mTheoraInfo.height - mHeight) / 2;
00455         //
00456         //unsigned long locYBuffSize = mYUV.y_height * mYUV.y_width;
00457         //mYUV.y                                =       new char[locYBuffSize];
00458         //mYUV.u                                =       new char[locYBuffSize/4];
00459         //mYUV.v                                =       new char[locYBuffSize/4];
00460 
00463 
00470         //
00471 
00473         //unsigned long locNum = (((double)10000000) / ((double)mVideoFormat->AvgTimePerFrame)) + (double)0.5;
00474 
00476         //mTheoraInfo.fps_numerator = locNum;
00477         //mTheoraInfo.fps_denominator = 1;
00478         //
00479         //mTheoraInfo.aspect_numerator=0;
00480         //mTheoraInfo.aspect_denominator=0;
00481         //
00482         //mTheoraInfo.colorspace=OC_CS_UNSPECIFIED;             //YV12
00483         //mTheoraInfo.target_bitrate=400000; //mVideoFormat->dwBitRate;
00484 
00486         //mTheoraInfo.quality=30; //video_q;
00487 
00488         //mTheoraInfo.dropframes_p=0;
00489         //mTheoraInfo.quick_p=1;
00490         //mTheoraInfo.keyframe_auto_p=1;
00491         //mTheoraInfo.keyframe_frequency=64;   //If you change this... change the logged value below
00492         //mTheoraInfo.keyframe_frequency_force=64;  //ditto
00493         //mTheoraInfo.keyframe_data_target_bitrate=mTheoraInfo.target_bitrate*1.5;
00494         //mTheoraInfo.keyframe_auto_threshold=80;
00495         //mTheoraInfo.keyframe_mindistance=8;
00496         //mTheoraInfo.noise_sensitivity=1; 
00497 
00498         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.frameRateNumerator = locNum;
00499         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.frameRateDenominator = 1;
00500         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.maxKeyframeInterval = 6;   //log2(keyframe_freq) from above
00501         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.frameHeight = mHeight;
00502         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.frameWidth = mWidth;
00503         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.colourSpace = OC_CS_UNSPECIFIED;
00504         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.height = mTheoraInfo.height;
00505         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.width = mTheoraInfo.width;
00506         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.xOffset = mXOffset;
00507         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.yOffset = mYOffset;
00508         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.aspectDenominator = 0;
00509         //((TheoraEncodeFilter*)mParentFilter)->mTheoraFormatBlock.aspectNumerator = 0;
00510 
00511         return true;
00512 
00513 }
00514 void DiracEncodeInputPin::DestroyCodec() {
00515         //fish_sound_delete(mFishSound);
00516         //mFishSound = NULL;
00517 }
00518 
00519 
00520 
00521 HRESULT DiracEncodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00522         AbstractVideoEncodeInputPin::SetMediaType(inMediaType);
00523 
00524         ConstructCodec();
00525 
00526 
00527         return S_OK;
00528         
00529 }
00530 

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