[Datatype-cvs] mp3/fileformat mp3ff.cpp,1.36,1.37
ehodge at helixcommunity.org ehodge at helixcommunity.orgUpdate of /cvsroot/datatype/mp3/fileformat In directory cvs-new:/tmp/cvs-serv741 Modified Files: mp3ff.cpp Log Message: Implements IHXMediaBytesToMediaDur interface which is used in progressive-download situation. It translates bytes downloaded so far into a duration (that is the minimum of all the streams' durs at that point in the file). Also can be called to get complete- file's dur. Currently, local file objects are the only ones that access these methods. TODO: Remove prog-down work-around code from CRnMp3Fmt::GetPacket and from statDone and replace stat...etc. with mediaBytesToMediaDur...::ConvertFileOffsetToDur call. If m_ulFileSize != ulFileSize then call UpdateDuration(). Reviewed by: ehyche at real.com Index: mp3ff.cpp =================================================================== RCS file: /cvsroot/datatype/mp3/fileformat/mp3ff.cpp,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- mp3ff.cpp 24 Jun 2004 06:10:46 -0000 1.36 +++ mp3ff.cpp 13 Aug 2004 08:51:12 -0000 1.37 @@ -60,6 +60,9 @@ #include "hxbuffer.h" #include "hxprefs.h" #include "hxtick.h" +#if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS) +#include "hxprdnld.h" // IHXMediaBytesToMediaDur +#endif /* #if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS) */ #include "ringbuf.h" @@ -310,6 +313,107 @@ return retVal; } +#if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS) +/////////////////////////////////////////////////////////////////////////////// +// IHXMediaBytesToMediaDur methods ref: hxprdnld.h +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Method: +// IHXMediaBytesToMediaDur::ConvertFileOffsetToDur ref: hxprdnld.h +// Purpose: +// Gets the duration associated with the +// +// With ulLastReadOffset, the FF can match up where its last Read +// was with what it knows the dur was for that Read and thus +// better estimate the duration at the given file offset. +// +// It is possible that the duration is resolved to be indefinite +// in which case HX_PROGDOWNLD_INDEFINITE_DURATION is returned. +// +// Also, ulFileSize can be HX_PROGDOWNLD_UKNOWN_FILE_SIZE and +// this method should still try to associate a duration with the +// bytes up to the last read. +// +// If this fails (returns HXR_FAIL) then calling object should +// instead notify its IHXPDStatusMgr that the file size +// changed but that it doesn't have new dur info. That way, at +// least the observer can know (& show) progress is happening. +/// +STDMETHODIMP +CRnMp3Fmt::ConvertFileOffsetToDur(UINT32 /*IN*/ ulLastReadOffset, + UINT32 /*IN*/ ulFileSize, + REF(UINT32) /*OUT*/ ulREFDur) +{ + HX_RESULT hxrslt = HXR_FAIL; + + // /XXXEH- is there something useful we could do, here, with ulFileSize? + + HX_ASSERT(ulLastReadOffset > m_ulFileOffset); + if (ulLastReadOffset > m_ulFileOffset) + { + double dDur = ( (double)(ulLastReadOffset - m_ulFileOffset) / + (double)(m_Info.ulBitRate>>3) ) * 1000.0; + ulREFDur = (UINT32)dDur; + hxrslt = HXR_OK; + } + + return hxrslt; +} + +/////////////////////////////////////////////////////////////////////////////// +// Method: +// IHXMediaBytesToMediaDur::GetFileDuration ref: hxprdnld.h +// Purpose: +// Gets the duration associated with the entire file. +// +// It is possible that the duration is resolved to be indefinite +// in which case HX_PROGDOWNLD_INDEFINITE_DURATION is returned. +// +// Callers can pass in HX_PROGDOWNLD_UKNOWN_FILE_SIZE if ulFileSize +// is not known to them and FF may still be able to determine +// ulREFDur. However, if FF can't determine the duration of whole +// file (e.g., in a SMIL2 file), it returns HXR_FAIL and ulREFDur is +// set to HX_PROGDOWNLD_UNKNOWN_DURATION. +/// +STDMETHODIMP +CRnMp3Fmt::GetFileDuration(UINT32 /*IN*/ ulFileSize, + REF(UINT32) /*OUT*/ ulREFDur) +{ + HX_RESULT hxrslt = HXR_OK; + + // /XXXEH- is there something useful we could do, here, with ulFileSize? + + ulREFDur = m_ulCurrentDuration; + if (0 == m_ulCurrentDuration) + { + if (m_Info.ulBitRate>>3 > 0) + { + double dDur = 0.0; + UINT32 ulTotalFileSize = ulFileSize; + if (HX_PROGDOWNLD_UNKNOWN_FILE_SIZE == ulTotalFileSize) + { + // /XXXEH- do we want to return HX_PROGDOWNLD_UNKNOWN_DURATION here + // instead? m_ulFileSize is not the full file size if it's still + // downloading: + ulTotalFileSize = m_ulFileSize; + } + dDur = (ulTotalFileSize - m_ulFileOffset) / + (double)(m_Info.ulBitRate>>3) * 1000.0; + ulREFDur = (UINT32)dDur; + } + else // /We don't know our bitrate, thus we haven't parsed our header yet: + { + hxrslt = HXR_FAIL; + ulREFDur = HX_PROGDOWNLD_UNKNOWN_DURATION; + } + } + + return hxrslt; +} +#endif /* end #if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS). */ + + /////////////////////////////////////////////////////////////////////////////// // IHXFileFormatObject::GetFileFormatInfo ref: hxformt.h // @@ -1965,6 +2069,14 @@ return HXR_OK; } #endif +#if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS) + else if (IsEqualIID(interfaceID, IID_IHXMediaBytesToMediaDur)) + { + AddRef(); + *ppInterfaceObj = (IHXMediaBytesToMediaDur*) this; + return HXR_OK; + } +#endif /* #if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS). */ // No other interfaces are supported *ppInterfaceObj = NULL;