[prev in list] [next in list] [prev in thread] [next in thread]
List: helix-filesystem-cvs
Subject: [Filesystem-cvs] local/mini minifileobj.cpp,1.39.14.1,1.39.14.2
From: dushyantvipradas () helixcommunity ! org
Date: 2009-12-02 17:00:23
Message-ID: 200912021813.nB2ID8Z6020487 () mailer ! progressive-comp ! com
[Download RAW message or body]
Update of /cvsroot/filesystem/local/mini
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv10461
Modified Files:
Tag: hxclient_4_2_0_brizo
minifileobj.cpp
Log Message:
Modified by: ext-dushyant.vipradas@nokia.com
Reviewed by:
Date: 11/23/2009
Project: SymbianMmf_wm
ErrorId: JRAH-7XXTAD
Overview: Avi 2.0 support. All the files greater than 1gb are created as per AVI2.0 \
OpenDML specification. The file contains a new index table and the old style index \
table is options in these file. All the changes are made under helix level feature \
flag 'HELIX_FEATURE_AVI2'. Note:
- Current support is limited to files having 'superindex' and 'standardindex'. Files \
containing 'fieldindex' are not supported.
Files Added:
None.
Files Modified:
\datatype\avi\fileformat\aviffpln.cpp
\datatype\avi\fileformat\avistrm.cpp
\datatype\avi\fileformat\pub\aviffpln.h
\datatype\avi\fileformat\pub\avistrm.h
\common\fileio\platform\symbian\hxdatasource_ccontent.cpp
\filesystem\local\mini\minifileobj.cpp
Image Size and Heap Use impact: minor
Module Release testing (STIF) : N/A
Test case(s) Added : No.
Memory leak check performed: Yes.
Platforms and Profiles Build Verified:
helix-client-s60-52-mmf-mdf-dsp
Platforms and Profiles Functionality verified: winscw, armv5
Branch: 210Cays, 420Cays, HEAD
Index: hxdatasource_ccontent.cpp
===================================================================
RCS file: /cvsroot/common/fileio/platform/symbian/hxdatasource_ccontent.cpp,v
retrieving revision 1.5.38.2
diff -w -u -b -r1.5.38.2 hxdatasource_ccontent.cpp
--- hxdatasource_ccontent.cpp 3 Nov 2009 18:43:29 -0000 1.5.38.2
+++ hxdatasource_ccontent.cpp 2 Dec 2009 16:46:37 -0000
@@ -859,8 +859,15 @@
if(hxr == HXR_OK)
{
+ if(offset >= 0x80000000 && offset < 0xFFFFFFFF)
+ {
+ seekresult = DoSeek64(offset,fromWhere);
+ }
+ else
+ {
seekresult = DoSeek(offset,fromWhere);
}
+ }
if( seekresult == HXR_OK )
{
? Makefile
? Umakefil.upp
? aviffdll.mak
? aviffdll.upp
? avifflib.mak
? avifflib.upp
? avifformat.def
? avifformat.uid.cpp
? avifformat_dll_stub.c
? avifformat_ordinal.dat
? diff.txt
? winscw-dbg32
Index: aviffpln.cpp
===================================================================
RCS file: /cvsroot/datatype/avi/fileformat/aviffpln.cpp,v
retrieving revision 1.12
diff -w -u -b -r1.12 aviffpln.cpp
--- aviffpln.cpp 21 Jan 2009 16:19:09 -0000 1.12
+++ aviffpln.cpp 2 Dec 2009 16:48:49 -0000
@@ -94,6 +94,14 @@
#define AVI_AUTHOR_CHUNK 0x49415254 /* 'IART' */
#define AVI_COPYRIGHT_CHUNK 0x49434f50 /* 'ICOP' */
+#ifdef HELIX_FEATURE_AVI2
+#define AVI_INDX_CHUNK 0x696e6478 /* 'indx' */
+#define AVI_VPRP_CHUNK 0x76707270 /* 'vprp' */
+#define AVI_ODML_OBJECT 0x6f646d6c /* 'odml' */
+#define AVI_DMLH_CHUNK 0x646d6c68 /* 'dmlh' */
+#endif
+
+
// TODO: Map these types explicitly:
#define AVI_H261_VIDEO 0x31363248 /* '162H' */
#define AVI_H263_VIDEO 0x3336324D /* '362M' :XXXEH- why 'M', not 'H'? */
@@ -200,6 +208,9 @@
, m_pszTitle(NULL)
, m_pszAuthor(NULL)
, m_pszCopyright(NULL)
+#ifdef HELIX_FEATURE_AVI2
+ , m_bHasAviOdmlIndex(FALSE)
+#endif
, m_state(AS_InitPending)
{
@@ -598,7 +609,13 @@
{
CAVIStream* pStream = (CAVIStream*) m_streamArray[usStream];
HX_ASSERT_VALID_PTR(pStream);
+
+#ifndef HELIX_FEATURE_AVI2
+ if(m_pIndex)
+ {
pStream->SetIndex(m_pIndex);
+ }
+#endif
if (SUCCEEDED(pStream->GetHeader(pHeader)))
{
@@ -936,6 +953,10 @@
case AVI_STRF_CHUNK:
case AVI_STRH_CHUNK:
case AVI_STRD_CHUNK:
+#ifdef HELIX_FEATURE_AVI2
+ case AVI_VPRP_CHUNK:
+ case AVI_INDX_CHUNK:
+#endif
m_state = AS_STRLRead;
m_pGeneralReader->Read(len);
break;
@@ -946,6 +967,13 @@
m_state = AS_STRLDescend;
m_pGeneralReader->Descend();
}
+#ifdef HELIX_FEATURE_AVI2
+ else if (m_pGeneralReader->GetChunkType() == \
AVI_ODML_OBJECT) + {
+ m_state = AS_ODMLAscend;
+ m_pGeneralReader->Ascend();
+ }
+#endif
else
{
// m_state = AS_STRLScanDone;
@@ -958,6 +986,34 @@
}
break;
+#ifdef HELIX_FEATURE_AVI2
+ case AS_ODMLFind:
+ if (FAILED(status))
+ {
+ m_state = AS_InitPending;
+ m_pFFResponse->FileHeaderReady(status, NULL);
+ }
+ else if (m_pGeneralReader->GetListType() == AVI_ODML_OBJECT)
+ {
+ m_state = AS_ODMLDescend;
+ m_pGeneralReader->Descend();
+ }
+ break;
+
+ case AS_ODMLScan:
+ if (FAILED(status))
+ {
+ m_state = AS_INFOFind;
+ m_pGeneralReader->FindChunk(AVI_LIST_OBJECT, FALSE);
+ }
+ else if(m_pGeneralReader->GetChunkType() == AVI_DMLH_CHUNK)
+ {
+ m_state = AS_DMLHRead;
+ m_pGeneralReader->Read(len);
+ }
+ break;
+#endif
+
case AS_INFOFind:
if (FAILED(status))
{
@@ -1063,6 +1119,20 @@
m_pGeneralReader->FindNextChunk();
}
break;
+#ifdef HELIX_FEATURE_AVI2
+ case AS_ODMLDescend:
+ if ( status != HXR_OK )
+ {
+ m_state = AS_InitPending;
+ m_pFFResponse->FileHeaderReady(status, NULL);
+ }
+ else
+ {
+ m_state = AS_ODMLScan;
+ m_pGeneralReader->FindChunk(AVI_DMLH_CHUNK, TRUE);
+ }
+ break;
+#endif
case AS_INFODescend:
if ( status != HXR_OK)
{
@@ -1112,7 +1182,12 @@
m_state = AS_INFOFind;
m_pGeneralReader->FindChunk(AVI_LIST_OBJECT, FALSE);
break;
-
+#ifdef HELIX_FEATURE_AVI2
+ case AS_ODMLAscend:
+ m_state = AS_ODMLFind;
+ m_pGeneralReader->FindChunk(AVI_LIST_OBJECT, TRUE);
+ break;
+#endif
case AS_INFOAscend:
{
IHXValues* pFileHeader = GetHeader();
@@ -1142,6 +1217,7 @@
{
HXLOGL4(HXLOG_AVIX,"CAVIFileFormat[%p]::RIFFReadDone(%lx)\tstate=%lu", this, \
status, m_state); HX_ASSERT(SUCCEEDED(status));
+ HX_RESULT result = HXR_OK;
if (m_state < AS_AVIHRead ||
m_state > AS_INFORead)
@@ -1212,12 +1288,46 @@
pStream->SetOpaque(pBuffer);
}
break;
+#ifdef HELIX_FEATURE_AVI2
+ case AVI_VPRP_CHUNK:
+ {
+ // Not_Implemented
}
+ break;
+ case AVI_INDX_CHUNK:
+ {
+ m_bHasAviOdmlIndex = TRUE;
+ // We initialize the stream here when we find that the file \
contains + // AVI2.0 ODML style index. We only read super index.
+ m_state = AS_GetODMLStreamFilePending;
+ const char* szFilename = NULL;
+ m_pFile->GetFilename(szFilename);
+ m_pFileSystemManager->GetRelativeFileObject(m_pFile, szFilename);
+
+
+ CAVIStream* pStream = (CAVIStream*) m_streamArray[m_usStreamTarget \
-1]; + HX_ASSERT(pStream);
+ result = pStream->SetAVIXIndex(pBuffer, \
m_pGeneralReader->GetOffset()); + m_state = AS_STRLRead;
+ }
+ break;
+#endif
+ }
m_state = AS_STRLScan;
m_pGeneralReader->FindNextChunk();
break;
+#ifdef HELIX_FEATURE_AVI2
+ case AS_DMLHRead:
+ if(m_pGeneralReader->GetChunkType()==AVI_DMLH_CHUNK)
+ {
+ result = SetODMLHeader(pBuffer);
+ }
+ m_state = AS_INFOFind;
+ m_pGeneralReader->FindChunk(AVI_LIST_OBJECT, FALSE);
+ break;
+#endif
case AS_INFORead:
SetInfo(pBuffer, m_pGeneralReader->GetChunkType());
@@ -1227,10 +1337,10 @@
default:
HX_ASSERT(FALSE);
- return HXR_UNEXPECTED;
+ result = HXR_UNEXPECTED;
}
- return HXR_OK;
+ return result;
}
void CAVIFileFormat::SetInfo(IHXBuffer* pBuffer, UINT32 ulChunkType)
@@ -1305,6 +1415,29 @@
return HXR_OK;
}
+#ifdef HELIX_FEATURE_AVI2
+HX_RESULT CAVIFileFormat::SetODMLHeader(IHXBuffer* pBuffer)
+{
+ HXLOGL2(HXLOG_AVIX,"CAVIFileFormat[%p]::SetODMLHeader\tstate=%lu", this, \
m_state); + HX_ASSERT_VALID_PTR(pBuffer);
+ HX_RESULT result = HXR_OK;
+
+ UINT32 len = pBuffer->GetSize();
+ UCHAR* buf = pBuffer->GetBuffer();
+
+ if (len < sizeof(m_odmlheader))
+ {
+ HX_ASSERT(FALSE);
+ result = HXR_FAIL;
+ }
+ else
+ {
+ m_odmlheader.ulTotalFrames = LE32_TO_HOST( *(UINT32*) &buf[0]);
+ }
+ return result;
+}
+#endif
+
STDMETHODIMP
CAVIFileFormat::RIFFSeekDone(HX_RESULT status)
{
@@ -1335,6 +1468,13 @@
m_pGeneralReader->Ascend();
break;
}
+#ifdef HELIX_FEATURE_AVI2
+ case AS_ODMLScanDone:
+ {
+ // Not Implemented.
+ }
+ break;
+#endif
default:
HX_ASSERT(FALSE);
@@ -1354,14 +1494,28 @@
HXLOGL4(HXLOG_AVIX,"CAVIFileFormat[%p]::FileObjectReady\tstate=%lu", this, \
m_state); HX_ASSERT(SUCCEEDED(status));
HX_ASSERT_VALID_PTR(pObject);
+#ifdef HELIX_FEATURE_AVI2
+ HX_ASSERT(m_state == AS_GetIndexFilePending || m_state == \
AS_GetStreamFilePending || m_state == AS_GetODMLStreamFilePending); +#else
HX_ASSERT(m_state == AS_GetIndexFilePending || m_state == \
AS_GetStreamFilePending); +#endif
HX_RESULT pnr = status;
switch ( m_state )
{
case AS_GetStreamFilePending:
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ // read the complete standard index for playback.
+ m_state = AS_IOEvent;
+ IOEvent();
+ }
+ else
+#endif
+ {
// we are going to give the file object to the sub stream,
// it is responsible for closing the file when we tell it to,
// we don't keep a reference to it.
@@ -1386,10 +1540,36 @@
{
m_pFFResponse->PacketReady(pnr, NULL);
}
+ }
+ break;
+#ifdef HELIX_FEATURE_AVI2
+ case AS_GetODMLStreamFilePending:
+ // we are going to give the file object to the sub stream,
+ // it is responsible for closing the file when we tell it to,
+ // we don't keep a reference to it.
+ IHXFileObject* pStreamFile;
+ if (SUCCEEDED(status) && (HXR_OK == (pnr = \
pObject->QueryInterface(IID_IHXFileObject, + \
(void**)&pStreamFile)))) + {
+ CAVIStream* pStream = (CAVIStream*) \
m_streamArray[m_usStreamTarget-1]; + HX_ASSERT(pStream);
+ HX_ASSERT( !((CAVIStream*) \
m_streamArray[m_usStreamTarget-1])->ReadInitialized());
+ ((CAVIStream*) \
m_streamArray[m_usStreamTarget-1])->InitForReading(m_pContext, pStreamFile); + \
HX_RELEASE(pStreamFile); + }
break;
+#endif
case AS_GetIndexFilePending:
-
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ m_state = AS_IndexFileInit;
+ IOEvent();
+ }
+ else
+#endif
+ {
m_state = AS_IndexFileInit;
HX_ASSERT(m_ulMOVIOffset);
IHXFileObject* pIndexFile;
@@ -1422,7 +1602,7 @@
// after new, addref m_pIndex
// m_pIndex->AddRef();
-
+ }
break;
default:
@@ -1580,12 +1760,39 @@
// assert pending packet counts are zero
// Fill index:
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ UINT32 uStreamSliceLoaded = 0;
+ for (UINT16 i = 0; i < m_streamArray.GetSize(); ++i)
+ {
+
+ CAVIStream* pStream = (CAVIStream*) m_streamArray[i];
+ HX_ASSERT(pStream);
+
+ if (pStream->CanLoadSlice())
+ {
+ uStreamSliceLoaded++;
+ m_state = AS_IOEvent;
+ pStream->GetNextSlice();
+ continue;
+ }
+ }
+ if (uStreamSliceLoaded == m_streamArray.GetSize())
+ {
+ return ;
+ }
+ }
+ else
+#endif
+ {
if (m_pIndex->CanLoadSlice())
{
m_state = AS_IOEvent;
m_pIndex->GetNextSlice();
return;
}
+ }
// Load chunks until all streams are double buffered
// Many slight optimations could be made in this method.
@@ -1631,12 +1838,39 @@
while (lEarliestStream >= 0);
// Fill index:
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ UINT32 uStreamSliceLoaded = 0;
+ for (UINT16 i = 0; i < m_streamArray.GetSize(); ++i)
+ {
+
+ CAVIStream* pStream = (CAVIStream*) m_streamArray[i];
+ HX_ASSERT(pStream);
+
+ if (pStream->CanLoadSlice())
+ {
+ uStreamSliceLoaded++;
+ m_state = AS_IOEvent;
+ pStream->GetNextSlice();
+ continue;
+ }
+ }
+ if (uStreamSliceLoaded == m_streamArray.GetSize())
+ {
+ return ;
+ }
+ }
+ else
+#endif
+ {
if (m_pIndex->CanLoadSlice())
{
m_state = AS_IOEvent;
m_pIndex->GetNextSlice();
return;
}
+ }
do
{
@@ -1689,12 +1923,33 @@
}
// Prefetch index:
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ for (UINT16 i = 0; i < m_streamArray.GetSize(); ++i)
+ {
+
+ CAVIStream* pStream = (CAVIStream*) m_streamArray[i];
+ HX_ASSERT(pStream);
+
+ if (pStream->CanLoadSlice())
+ {
+ m_state = AS_IOEvent;
+ pStream->GetNextSlice();
+ continue;
+ }
+ }
+ }
+ else
+#endif
+ {
if (m_pIndex->CanPreloadSlice())
{
m_state = AS_IOEvent;
m_pIndex->GetNextSlice();
}
}
+}
IHXValues* CAVIFileFormat::GetHeader()
{
@@ -1781,7 +2036,13 @@
if (pStream->PendingHeaderRequest())
{
+#ifndef HELIX_FEATURE_AVI2
+ if (m_pIndex)
+ {
+ // AVIIndex is not needed if ODMLIndex is found.
pStream->SetIndex(m_pIndex);
+ }
+#endif
IHXValues* pHeader = NULL;
if (SUCCEEDED(m_pCommonClassFactory->CreateInstance(CLSID_IHXValues,
\
(void**)&pHeader)))
Index: avistrm.cpp
===================================================================
RCS file: /cvsroot/datatype/avi/fileformat/avistrm.cpp,v
retrieving revision 1.22
diff -w -u -b -r1.22 avistrm.cpp
--- avistrm.cpp 8 Jul 2009 02:40:21 -0000 1.22
+++ avistrm.cpp 2 Dec 2009 16:48:49 -0000
@@ -85,6 +85,16 @@
#define MAX_AUDIO_PREROLL 30000
#ifdef NET_ENDIAN
+
+#define LE64_TO_HOST(x) ((x << 56) | \
+ (x << 40 & 0x00FF000000000000) | \
+ (x << 24 & 0x0000FF0000000000) | \
+ (x << 8 & 0x000000FF00000000) | \
+ (x >> 8 & 0x00000000FF000000) | \
+ (x >> 24 & 0x0000000000FF0000) | \
+ (x >> 40 & 0x000000000000FF00) | \
+ (x >> 56 & 0x00000000000000FF))
+
#define LE32_TO_HOST(x) ((x << 24) | \
(x << 8 & 0x00FF0000) | \
(x >> 8 & 0x0000FF00) | \
@@ -94,6 +104,8 @@
#define HOST_TO_LE16(x) (LE16_TO_HOST(x))
#define HOST_TO_LE32(x) (LE32_TO_HOST(x))
#else
+
+#define LE64_TO_HOST(x) (x)
#define LE32_TO_HOST(x) (x)
#define LE16_TO_HOST(x) (x)
#define HOST_TO_LE16(x) (x)
@@ -315,6 +327,19 @@
, m_ulSeekTime (0)
, m_pFile (NULL)
, m_ulTime(0)
+ , m_ulMaxByteDeflict (0)
+ , m_ulMaxChunkSize (0)
+ , m_ulAvgChunkSize(0)
+#ifdef HELIX_FEATURE_AVI2
+ , m_bHasAviOdmlIndex(FALSE)
+ , m_ulSizeOfCurrentChunk(0)
+ , m_ulCurrentSuperIndexEntry(0)
+ , m_ullBytesTotal(0)
+ , m_ulTotalNumberOfChunks(0)
+ , m_pStdIndex(NULL)
+ , m_pSuperIndex(NULL)
+ , m_ulTargetSeekTime(0)
+#endif
{
HXLOGL2(HXLOG_AVIX, "CAVIStream[%p]::CAVIStream() CTOR", this);
HX_ASSERT_VALID_PTR(m_pOuter);
@@ -407,6 +432,81 @@
return result;
}
+#ifdef HELIX_FEATURE_AVI2
+/////////////////////////////////////////////////////////////////////////
+/* CAVIStream::SetAVIXIndex
+ Currently we are only supporitng SuperIndex and StandardIndex structure.
+ We do not support index_to_field type in superindex and
+ index_to_fields type StandardIndex. Support planned at later stage. \
+*/
+/////////////////////////////////////////////////////////////////////////
+HX_RESULT CAVIStream::SetAVIXIndex(IHXBuffer* pAVIXIndex, UINT32 ulOffset)
+{
+ HXLOGL2(HXLOG_AVIX,"CAVIStream[%p]::SetAVIXIndex()", this);
+ HX_ASSERT(pAVIXIndex);
+ HX_RESULT result = HXR_OK;
+
+ UCHAR* buf;
+ ULONG32 len;
+
+ m_bHasAviOdmlIndex = TRUE;
+
+ if (pAVIXIndex && SUCCEEDED(pAVIXIndex->Get(buf, len)))
+ {
+
+ HX_DELETE(m_pSuperIndex);
+ m_pSuperIndex = new AviSuperIndex;
+ AviSuperIndex* pSuperIndex = (AviSuperIndex*) buf;
+
+ m_pSuperIndex->usLongsPerEntry = \
LE16_TO_HOST(pSuperIndex->usLongsPerEntry); + m_pSuperIndex->ulNEntriesInUse \
= LE32_TO_HOST(pSuperIndex->ulNEntriesInUse); + m_pSuperIndex->ulChunkId \
= LE32_TO_HOST(pSuperIndex->ulChunkId); + m_pSuperIndex->ulReserved[3] = \
pSuperIndex->ulReserved[3]; +
+ if(m_pSuperIndex->ucIndexType == 0x01) //AVI_INDEX_OF_CHUNKS
+ {
+ if(m_pSuperIndex->ucIndexSubType == 0) // AVI_STD_INDEX
+ {
+ m_pSuperIndex->aIndex[0].llOffset = ulOffset;
+ m_pSuperIndex->aIndex[0].ulSize = len;
+ m_pSuperIndex->aIndex[0].ulDuration = pSuperIndex->ulNEntriesInUse; \
+ m_pSuperIndex->usLongsPerEntry = 4; // needs to be 4.
+ m_pSuperIndex->ucIndexSubType = 0; // treating as standard \
index + m_pSuperIndex->ucIndexType = 0; // treating as \
standard index + m_pSuperIndex->ulNEntriesInUse = 1;
+ }
+ else // AVI_FIELD_INDEX
+ {
+ // We currently do not support field index chunks.
+ result = HXR_FAIL;
+ }
+ }
+ else // It must be an AVI_INDEX_OF_INDEXES
+ {
+ m_pSuperIndex->ucIndexSubType = pSuperIndex->ucIndexSubType;
+ m_pSuperIndex->ucIndexType = pSuperIndex->ucIndexType;
+ if(m_pSuperIndex->ulNEntriesInUse <= MAX_INDEX_CHUNKS)
+ {
+ for(int i=0 ; i < m_pSuperIndex->ulNEntriesInUse ; i++)
+ {
+ m_pSuperIndex->aIndex[i].llOffset = \
LE64_TO_HOST(pSuperIndex->aIndex[i].llOffset); + \
m_pSuperIndex->aIndex[i].ulSize = LE32_TO_HOST(pSuperIndex->aIndex[i].ulSize); + \
m_pSuperIndex->aIndex[i].ulDuration = \
LE32_TO_HOST(pSuperIndex->aIndex[i].ulDuration); \
+ }
+ }
+ else
+ {
+ result = HXR_FAIL;
+ }
+ }
+ }
+ else
+ {
+ result = HXR_FAIL;
+ }
+ return result;
+}
+#endif
/////////////////////////////////////////////////////////////////////////
// CAVIStream::SetFormat
@@ -748,7 +848,18 @@
m_fChunksPerSecond = (double) m_header.ulRate / m_header.ulScale;
m_fSamplesPerSecond = m_fChunksPerSecond;
- INT32 ulMaxChunkSize = m_pIndex->GetMaxChunkSize(m_usStream);
+ INT32 ulMaxChunkSize = 0;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ ulMaxChunkSize = m_ulMaxChunkSize;
+ }
+ else
+#endif
+ {
+ ulMaxChunkSize = m_pIndex->GetMaxChunkSize(m_usStream);
+ }
+
if (m_bLocalPlayback)
{
@@ -773,7 +884,18 @@
// To do: set min packet size as a function of the block
// alignment; support in packetizer
- INT32 ulMaxPacketSize = m_pIndex->GetMaxChunkSize(m_usStream);
+ INT32 ulMaxPacketSize = 0;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ ulMaxPacketSize = m_ulMaxChunkSize;
+ }
+ else
+#endif
+ {
+ ulMaxPacketSize = m_pIndex->GetMaxChunkSize(m_usStream);
+ }
+
strcpy(szStreamName, "An audio stream");
@@ -950,7 +1072,18 @@
pHeader->SetPropertyULONG32("Channels", pWaveInfo->usChannels);
HXLOGL4(HXLOG_AVIX,"\t\tChannels:\t%lu", pWaveInfo->usChannels);
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ m_fChunksPerSecond = m_ulTotalNumberOfChunks / ((double) \
m_ullBytesTotal / pWaveInfo->ulAvgBytesPerSec); + }
+ else
+#endif
+ {
m_fChunksPerSecond = m_pIndex->GetChunkTotal(m_usStream) / ((double) \
m_pIndex->GetByteTotal(m_usStream) / pWaveInfo->ulAvgBytesPerSec); + }
+
+
m_fSamplesPerSecond = (double) m_header.ulRate / m_header.ulScale;
break;
}
@@ -1014,16 +1147,47 @@
HXLOGL4(HXLOG_AVIX,"\t\tDuration:\t%lu", (ULONG32) (((double) m_header.ulLength \
/ m_fSamplesPerSecond) * 1000));
// Max bit rate:
- pHeader->SetPropertyULONG32("MaxBitRate", (ULONG32) (8 * \
m_pIndex->GetMaxChunkSize(m_usStream) * m_fChunksPerSecond));
- HXLOGL4(HXLOG_AVIX,"\t\tMaxBitRate:\t%lu", (ULONG32) (8 * \
m_pIndex->GetMaxChunkSize(m_usStream) * m_fChunksPerSecond)); + UINT32 \
ulMaxChunkSize; +#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ ulMaxChunkSize = m_ulMaxChunkSize;
+ }
+ else
+#endif
+ {
+ ulMaxChunkSize = m_pIndex->GetMaxChunkSize(m_usStream);
+ }
+ pHeader->SetPropertyULONG32("MaxBitRate", (ULONG32) (8 * ulMaxChunkSize * \
m_fChunksPerSecond)); + HXLOGL4(HXLOG_AVIX,"\t\tMaxBitRate:\t%lu", (ULONG32) (8 * \
ulMaxChunkSize * m_fChunksPerSecond)); +
+#ifdef HELIX_FEATURE_AVI2
+ if(!m_bHasAviOdmlIndex) // m_ulAvgChunkSize for ODML case is calculated in \
riffreaddone. +#endif
+ {
+ m_ulAvgChunkSize = m_pIndex->GetAverageChunkSize(m_usStream);
+ }
+
// Averate bit rate:
- ULONG32 ulAverageBitrate = (ULONG32) (8 * \
m_pIndex->GetAverageChunkSize(m_usStream) * m_fChunksPerSecond); + ULONG32 \
ulAverageBitrate = (ULONG32) (8 * m_ulAvgChunkSize * m_fChunksPerSecond); \
pHeader->SetPropertyULONG32("AvgBitRate", ulAverageBitrate); \
HXLOGL4(HXLOG_AVIX,"\t\tAvgBitRate:\t%lu", ulAverageBitrate);
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ // m_uMaxByteDeflict value can be optimised
+ m_ulMaxByteDeflict = 0;
+ }
+ else
+#endif
+ {
+ m_ulMaxByteDeflict = m_pIndex->GetMaxByteDeflict(m_usStream);
+ }
+
// Preroll:
- UINT32 ulPreroll = (UINT32) (((double) m_pIndex->GetMaxByteDeflict(m_usStream) / \
ulAverageBitrate) * 1000); + UINT32 ulPreroll = (UINT32) (((double) \
m_ulMaxByteDeflict / ulAverageBitrate) * 1000);
if (IsAudio())
{
@@ -1198,6 +1362,38 @@
m_ulPendingPacketRequests = 0;
}
+#ifdef HELIX_FEATURE_AVI2
+HXBOOL CAVIStream::IsTargetChunkLoaded(UINT32 ulTargetChunk)
+{
+ HXBOOL result = HXR_OK;
+ UINT32 ulTargetSuperIndexChunk = 0;
+ UINT32 ulStartDuration = 0;
+ UINT32 ulEndDuration = 0;
+
+ while(ulTargetSuperIndexChunk < m_pSuperIndex->ulNEntriesInUse)
+ {
+ ulEndDuration += m_pSuperIndex->aIndex[ulTargetSuperIndexChunk].ulDuration;
+ if(ulTargetChunk >= ulStartDuration && ulTargetChunk < ulEndDuration)
+ {
+ break;
+ }
+ ulTargetSuperIndexChunk++;
+ ulStartDuration += m_pSuperIndex->aIndex[ulTargetSuperIndexChunk -1].ulDuration;
+ }
+ if(ulTargetSuperIndexChunk == m_ulCurrentSuperIndexEntry)
+ {
+ result = HXR_OK;
+ }
+ else
+ {
+ m_state = eSeekPending;
+ m_ulCurrentSuperIndexEntry = ulTargetSuperIndexChunk;
+ result = HXR_FAIL;
+ }
+ return result;
+}
+#endif
+
// Chunk handling methods:
/////////////////////////////////////////////////////////////////////////
// CAVIStream::Seek
@@ -1235,7 +1431,7 @@
while (ulTotalTime < ulTime)
{
- lLength = m_pIndex->GetChunkLength (m_usStream, ulTargetKeyChunk);
+ lLength = GetChunkLength (m_usStream, ulTargetKeyChunk);
if (lLength == -1)
{
@@ -1261,11 +1457,54 @@
{
ulTargetChunk = (UINT32) (ulTime / 1000.0 * m_fChunksPerSecond);
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ if(IsTargetChunkLoaded(ulTargetChunk))
+ {
+ UINT32 keyChunk = m_pStdIndex->aIndex[ulTargetChunk].ulSize & \
80000000; + if(keyChunk != 0) // Targetchunk is not a key chunk.
+ {
+ for(UINT32 ulTargetChunkLocation = 1 ; ulTargetChunkLocation < \
(10*m_fChunksPerSecond); ulTargetChunkLocation++) + { // we want to \
find the closet chunk within max 10 sec. + if(ulTargetChunk + \
ulTargetChunkLocation < m_pStdIndex->ulNEntriesInUse) + {
+ keyChunk = m_pStdIndex->aIndex[ulTargetChunk + \
ulTargetChunkLocation].ulSize & 80000000; + if(keyChunk == 0)
+ {
+ ulTargetChunk += ulTargetChunkLocation;
+ break;
+ }
+ }
+ if(ulTargetChunk - ulTargetChunkLocation >= 0)
+ {
+ keyChunk = m_pStdIndex->aIndex[ulTargetChunk - \
ulTargetChunkLocation].ulSize & 80000000; + if(keyChunk == 0)
+ {
+ ulTargetChunk -= ulTargetChunkLocation;
+ break;
+ }
+ }
+ }
+ }
+ ulTargetKeyChunkOffset = m_pStdIndex->llBaseOffset + \
m_pStdIndex->aIndex[ulTargetChunk].ulOffset; + ulTargetKeyChunk = \
ulTargetChunk; + }
+ else
+ {
+ m_ulTargetSeekTime = ulTime;
+ return;
+ }
+ }
+ else
+#endif
+ {
if (FAILED(m_pIndex->FindClosestKeyChunk(m_usStream, ulTargetChunk, \
ulTargetKeyChunkOffset, ulTargetKeyChunk))) {
bTargetKeyChunkFound = FALSE;
}
}
+ }
// Do we have the target keychunk already?
// TODO: Optimize for the case where we have a partial set of
@@ -1310,7 +1549,7 @@
pSwappedBuffer->Set(pUnswappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize());
SwapWordBytes((unsigned short*) pSwappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize() / 2); pNewPacket->Set(pSwappedBuffer, ulTime, \
m_usStream,
- HX_ASM_SWITCH_OFF, 0 && \
!m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk)); + \
HX_ASM_SWITCH_OFF, 0 && !IsKeyChunk(m_usStream, m_ulMinReadChunk)); \
HX_RELEASE(pSwappedBuffer); }
}
@@ -1369,7 +1608,7 @@
for (UINT32 i=0; i<m_ulMinReadChunk; i++)
{
- m_ulTotalBytesPacketised += m_pIndex->GetChunkLength (m_usStream, i);
+ m_ulTotalBytesPacketised += GetChunkLength (m_usStream, i);
}
m_ulTotalBytesRead = m_ulTotalBytesPacketised;
@@ -1423,6 +1662,7 @@
{
ulTime = (UINT32) ((m_ulMinReadChunk / m_fChunksPerSecond) * 1000);
}
+
HXLOGL4(HXLOG_AVIX,"CAVIStream[%p]::GetNextPacket()\tstream %d\tpacket \
time: %lu\t minreadchunk: %lu\n", this, m_usStream, ulTime, m_ulMinReadChunk);
// TODO: Set correct ASM rules
@@ -1437,7 +1677,7 @@
pSwappedBuffer->Set(pUnswappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize());
SwapWordBytes((unsigned short*) pSwappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize() / 2); pNewPacket->Set(pSwappedBuffer, ulTime, \
m_usStream,
- HX_ASM_SWITCH_OFF, 0 && \
!m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk)); + \
HX_ASM_SWITCH_OFF, 0 && !IsKeyChunk(m_usStream, m_ulMinReadChunk)); \
HX_RELEASE(pSwappedBuffer); }
}
@@ -1515,9 +1755,57 @@
UINT32 ulNextChunkOffset;
HX_RESULT indexResult;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+
+ if(m_state == eSeekPending)
+ {
+ // file seek pending.
+ m_pReader->FileSeek(m_pSuperIndex->aIndex[m_ulCurrentSuperIndexEntry].llOffset \
+ 8); + indexResult = HXR_FAIL; // We dont want to Seek or find any chunk and its \
not EOF + }
+ else if(m_ulMaxReadChunk < m_ulTotalNumberOfChunks)
+ {
+ // m_ulMaxReadChunk has values from 0 to end chunk number.
+ // It does not reset when we start playing from next stdindex chunk.
+ // Hence we want to find the closet chunk from the array of
+ // index_chunks. So we want to have the proper value of the
+ // target chunk in the currently loaded stdindex chunk.
+
+ UINT32 ulChunksInPreviousIndex = 0;
+ for(UINT32 counter=0 ; counter < m_ulCurrentSuperIndexEntry ; counter++)
+ {
+ ulChunksInPreviousIndex += m_pSuperIndex->aIndex[counter].ulDuration;
+ }
+
+ ulNextChunkOffset = m_pStdIndex->llBaseOffset + \
m_pStdIndex->aIndex[m_ulMaxReadChunk - ulChunksInPreviousIndex].ulOffset - 8; + \
m_ulChunkReadTarget = m_ulMaxReadChunk; + indexResult = HXR_OK;
+ }
+ else
+ {
+ if(m_ulCurrentSuperIndexEntry < m_pSuperIndex->ulNEntriesInUse)
+ {
+ m_state = eSuperIndexSeek;
+ m_ulCurrentSuperIndexEntry++;
+ m_pReader->FileSeek(m_pSuperIndex->aIndex[m_ulCurrentSuperIndexEntry].llOffset \
+ 8); + indexResult = HXR_FAIL; // We dont want to Seek or find any chunk
+ } // and its not EOF
+ else
+ {
+ // All the chunks are over. we have reached EOF
+ indexResult = HXR_CHUNK_MISSING;
+ }
+ }
+ }
+ else
+#endif
+ {
indexResult = m_pIndex->FindClosestChunk(m_usStream, m_ulMaxReadChunk,
ulNextChunkOffset,
m_ulChunkReadTarget);
+ }
// HX_ASSERT(m_ulMaxReadChunk == m_ulChunkReadTarget); // for indexed clips only
if(indexResult == HXR_OK || indexResult == HXR_NOT_INDEXABLE)
@@ -1650,7 +1938,19 @@
HX_ASSERT(m_state == ePreReader);
m_state = eReady;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ m_state = eSuperIndexSeek;
+ m_ulSizeOfCurrentChunk = \
m_pSuperIndex->aIndex[m_ulCurrentSuperIndexEntry].ulSize; // record size of current \
stdindexchunk to calculate the size of the + \
// all the chunks in the file. + \
m_pReader->FileSeek(m_pSuperIndex->aIndex[m_ulCurrentSuperIndexEntry].llOffset + 8); \
+ } + else
+#endif
+ {
m_pOuter->IOEvent();
+ }
return HXR_OK;
}
@@ -1687,7 +1987,12 @@
{
m_bRead = TRUE;
m_state = eReady;
+#ifdef HELIX_FEATURE_AVI2
+ if(!m_bHasAviOdmlIndex)
+#endif
+ {
m_pIndex->FileRead(TRUE);
+ }
m_pOuter->IOEvent();
return HXR_OK;
}
@@ -1707,7 +2012,12 @@
if (chunkTypeAV && (usStream == m_usStream))
{
+#ifdef HELIX_FEATURE_AVI2
+ if(!m_bHasAviOdmlIndex)
+#endif
+ {
m_pIndex->AddToIndex(usStream, m_ulChunkReadTarget, m_pReader->GetOffset() - \
8, len); + }
if (m_ulChunkReadTarget == m_ulMaxReadChunk)
{
@@ -1795,6 +2105,73 @@
STDMETHODIMP CAVIStream::RIFFReadDone(HX_RESULT status, IHXBuffer *pBuffer)
{
HXLOGL4(HXLOG_AVIX,"CAVIStream[%p]::RIFFReadDone()", this);
+ HX_RESULT result = HXR_OK;
+
+#ifdef HELIX_FEATURE_AVI2
+ if(m_state == eSuperIndexRead || m_state == eSeekPending)
+ {
+ UCHAR* buf = NULL;
+ UINT32 len = 0;
+ if (pBuffer && SUCCEEDED(pBuffer->Get(buf, len)))
+ {
+ HX_DELETE(m_pStdIndex);
+ m_pStdIndex = new AviStdIndex;
+ AviStdIndex* pStdIndex = (AviStdIndex*)buf;
+
+ m_pStdIndex->usLongsPerEntry = LE16_TO_HOST(pStdIndex->usLongsPerEntry);
+ m_pStdIndex->ulNEntriesInUse = LE32_TO_HOST(pStdIndex->ulNEntriesInUse);
+ m_pStdIndex->ulChunkId = LE32_TO_HOST(pStdIndex->ulChunkId);
+ m_pStdIndex->llBaseOffset = LE64_TO_HOST(pStdIndex->llBaseOffset);
+ m_pStdIndex->ucIndexSubType = pStdIndex->ucIndexSubType;
+ m_pStdIndex->ucIndexType = pStdIndex->ucIndexType;
+ m_ulTotalNumberOfChunks += pStdIndex->ulNEntriesInUse;
+
+
+ if(m_pStdIndex->ulNEntriesInUse <= STDIDX_ENTRIES_READ_AT_A_TIME)
+ {
+ for(int i=0 ; i < m_pStdIndex->ulNEntriesInUse ; i++)
+ {
+ m_pStdIndex->aIndex[i].ulOffset = \
LE32_TO_HOST(pStdIndex->aIndex[i].ulOffset); + \
m_pStdIndex->aIndex[i].ulSize = LE32_TO_HOST(pStdIndex->aIndex[i].ulSize); + \
+ m_ullBytesTotal = m_ullBytesTotal + \
((m_pStdIndex->aIndex[i].ulSize) & 0x3FFFFFFF); + \
if(m_ulMaxChunkSize < m_pStdIndex->aIndex[i].ulSize) + {
+ m_ulMaxChunkSize = (m_pStdIndex->aIndex[i].ulSize) & \
0x3FFFFFFF; // 31st bit is used to indicate if this is a key chunk + \
} // 1 - Not a \
key chunk. 0 - Key Chunk + }
+ m_ulAvgChunkSize = m_ullBytesTotal / m_ulTotalNumberOfChunks;
+
+
+ if(m_state == eSeekPending)
+ {
+ m_state = eChunkRead;
+ Seek(m_ulTargetSeekTime);
+ GetNextSlice();
+ }
+ else if(m_ulCurrentSuperIndexEntry == 0)
+ {
+ m_state = eReady;
+ }
+ else
+ {
+ GetNextSlice();
+ }
+ }
+ else
+ {
+ // Cannot read that many entries.
+ result = HXR_FAIL;
+ }
+ }
+ else
+ {
+ result = HXR_FAIL;
+ }
+ }
+ else
+#endif
+ {
HX_ASSERT(m_state == eChunkRead);
HX_ASSERT(CAVIFileFormat::GetStream(ENDIAN_SWAP_32(m_pReader->GetChunkType())) \
== m_usStream); HX_ASSERT(m_ulChunkReadTarget == m_ulMaxReadChunk);
@@ -1850,14 +2227,14 @@
pSwappedBuffer->Set(pUnswappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize());
SwapWordBytes((unsigned short*) pSwappedBuffer->GetBuffer(), \
pUnswappedBuffer->GetSize() / 2); pNewPacket->Set(pSwappedBuffer, ulTime, \
m_usStream,
- HX_ASM_SWITCH_OFF, 0 && \
!m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk)); + \
HX_ASM_SWITCH_OFF, 0 && !IsKeyChunk(m_usStream, m_ulMinReadChunk)); \
HX_RELEASE(pSwappedBuffer); }
}
else
{
pNewPacket->Set(pBuffer, ulTime, m_usStream,
- HX_ASM_SWITCH_OFF, 0 && \
!m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk)); + \
HX_ASM_SWITCH_OFF, 0 && !IsKeyChunk(m_usStream, m_ulMinReadChunk)); }
#ifdef USE_SIMPLE_SEGMENT_PAYLOAD
@@ -1884,7 +2261,7 @@
HX_ASSERT(!m_chunkPrefetchArray[m_ulMaxReadChunk % \
MAX_CHUNK_PREFETCH].pBuffer); HX_ADDREF(pBuffer);
m_chunkPrefetchArray[m_ulMaxReadChunk % MAX_CHUNK_PREFETCH].pBuffer = \
pBuffer;
- m_chunkPrefetchArray[m_ulMaxReadChunk % MAX_CHUNK_PREFETCH].bKeyChunk = \
m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk); + \
m_chunkPrefetchArray[m_ulMaxReadChunk % MAX_CHUNK_PREFETCH].bKeyChunk = \
IsKeyChunk(m_usStream, m_ulMinReadChunk); }
++m_ulMaxReadChunk;
@@ -1892,7 +2269,7 @@
m_ulTotalBytesRead += bufferSize;
m_pOuter->IOEvent();
-
+ }
return HXR_OK;
}
@@ -1900,9 +2277,27 @@
STDMETHODIMP CAVIStream::RIFFSeekDone(HX_RESULT status)
{
HXLOGL4(HXLOG_AVIX,"CAVIStream[%p]::RIFFSeekDone()", this);
+
+#ifdef HELIX_FEATURE_AVI2
+ HX_ASSERT(m_state == eChunkSeek ||m_state == eSuperIndexSeek || eSeekPending);
+#else
HX_ASSERT(m_state == eChunkSeek);
- HX_ASSERT(SUCCEEDED(status));
+#endif
+ HX_ASSERT(SUCCEEDED(status));
+#ifdef HELIX_FEATURE_AVI2
+ if(m_state == eSuperIndexSeek || m_state == eSeekPending)
+ {
+ HXLOGL2(HXLOG_AVIX,"CAVIStream[%p]::RIFFSeekDone(), \
m_ulCurrentSuperIndexEntry = %lu", this,m_ulCurrentSuperIndexEntry); + \
if(m_state == eSuperIndexSeek) + {
+ m_state = eSuperIndexRead;
+ }
+ m_pReader->Read(m_pSuperIndex->aIndex[m_ulCurrentSuperIndexEntry].ulSize); \
+ }
+ else
+#endif
+ {
if (m_bDiscardPendingIO)
{
// We've seeked since the I/O request; let the the outer object
@@ -1916,7 +2311,7 @@
// Call a chunk find to force the reader to scan the current chunk:
m_state = eChunkFind;
m_pReader->FindNextChunk();
-
+ }
return HXR_OK;
}
@@ -1993,6 +2388,11 @@
HX_RELEASE(m_pFile);
}
+#ifdef HELIX_FEATURE_AVI2
+ HX_DELETE(m_pStdIndex);
+ HX_DELETE(m_pSuperIndex);
+#endif
+
//HX_TRACE("CAVIFileFormat::CAVIStream::~CAVIStream()\n");
HX_RELEASE(m_pReader);
HX_VECTOR_DELETE(m_pFormat);
@@ -2001,3 +2401,44 @@
HX_RELEASE(m_pContext);
HX_RELEASE(m_pOuter);
}
+
+UINT32 CAVIStream::GetChunkLength(UINT16 m_usStream, UINT32 ulTargetKeyChunk)
+{
+ UINT32 lLength = 0;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+ if(ulTargetKeyChunk < m_pStdIndex->ulNEntriesInUse)
+ {
+ lLength = m_pStdIndex->aIndex[ulTargetKeyChunk].ulSize;
+ }
+ }
+ else
+#endif
+ {
+ lLength = m_pIndex->GetChunkLength (m_usStream, ulTargetKeyChunk);
+ }
+ return lLength;
+}
+
+HXBOOL CAVIStream::IsKeyChunk(UINT16 usStream, UINT32 ulTargetKeyChunk)
+{
+ HXBOOL result;
+#ifdef HELIX_FEATURE_AVI2
+ if(m_bHasAviOdmlIndex)
+ {
+
+ UINT32 ulChunksInPreviousIndex = 0;
+ for(UINT32 counter=0 ; counter < m_ulCurrentSuperIndexEntry ; counter++)
+ {
+ ulChunksInPreviousIndex += m_pSuperIndex->aIndex[counter].ulDuration;
+ }
+ result = ( 0 == (m_pStdIndex->aIndex[ulTargetKeyChunk - \
ulChunksInPreviousIndex].ulSize & (1<<31))? TRUE : FALSE); + }
+ else
+#endif
+ {
+ result = m_pIndex->IsKeyChunk(m_usStream, m_ulMinReadChunk);
+ }
+ return result;
+}
Index: pub/aviffpln.h
===================================================================
RCS file: /cvsroot/datatype/avi/fileformat/pub/aviffpln.h,v
retrieving revision 1.7
diff -w -u -b -r1.7 aviffpln.h
--- pub/aviffpln.h 14 Nov 2008 21:53:03 -0000 1.7
+++ pub/aviffpln.h 2 Dec 2009 16:48:49 -0000
@@ -312,6 +312,9 @@
IHXValues* GetHeader();
void SetInfo(IHXBuffer* pBuffer, UINT32 ulChunkType);
HX_RESULT SetHeader(IHXBuffer* pBuffer);
+#ifdef HELIX_FEATURE_AVI2
+ HX_RESULT SetODMLHeader(IHXBuffer* pBuffer);
+#endif
void IOEvent();
@@ -321,6 +324,13 @@
const char* m_pURL;
+#ifdef HELIX_FEATURE_AVI2
+ struct ODMLExtendedAVIHeader
+ {
+ UINT32 ulTotalFrames;
+ } m_odmlheader;
+#endif
+
#pragma pack(1)
typedef struct tag_MainHeader
{
@@ -362,6 +372,14 @@
, AS_STRLScanDone
, AS_STRLRead
, AS_STRLAscend
+#ifdef HELIX_FEATURE_AVI2
+ , AS_ODMLFind
+ , AS_ODMLDescend
+ , AS_ODMLScan
+ , AS_ODMLScanDone
+ , AS_ODMLAscend
+ , AS_DMLHRead
+#endif
, AS_HDRLAscend
, AS_INFOFind
, AS_INFODescend
@@ -371,6 +389,9 @@
, AS_GetIndexFilePending
, AS_IndexFileInit // StreamHeaderReady, triggered by \
GetStreamHeader , AS_GetStreamFilePending // triggered by GetPacket
+#ifdef HELIX_FEATURE_AVI2
+ , AS_GetODMLStreamFilePending // used to initialise stream for ODML index \
case +#endif
, AS_IOEvent // PacketReady
, AS_Ready
, AS_Closed
@@ -380,6 +401,9 @@
HXBOOL m_bSeekPriming;
BOOL m_bLocalPlayback;
+#ifdef HELIX_FEATURE_AVI2
+ HXBOOL m_bHasAviOdmlIndex;
+#endif
CHXPtrArray m_streamArray;
UINT16 m_usStreamTarget; // The current target of callbacks
Index: pub/avistrm.h
===================================================================
RCS file: /cvsroot/datatype/avi/fileformat/pub/avistrm.h,v
retrieving revision 1.10
diff -w -u -b -r1.10 avistrm.h
--- pub/avistrm.h 22 Jun 2009 02:01:36 -0000 1.10
+++ pub/avistrm.h 2 Dec 2009 16:48:49 -0000
@@ -60,6 +60,11 @@
#define PRIOR_SEEK_TIME 0
#define SIZE_OF_AVI_VIDEO_HEADER 48
+#ifdef HELIX_FEATURE_AVI2
+#define MAX_INDEX_CHUNKS 8
+#define STDIDX_ENTRIES_READ_AT_A_TIME (256*1024)
+#endif
+
class CAVIFileFormat;
class CAVIIndex;
@@ -88,6 +93,9 @@
HX_RESULT SetIndex(CAVIIndex* pIndex);
+#ifdef HELIX_FEATURE_AVI2
+ HX_RESULT SetAVIXIndex(IHXBuffer* pAVIXIndex, UINT32 ulOffset);
+#endif
void SetPendingHeaderRequest();
BOOL PendingHeaderRequest();
@@ -97,7 +105,6 @@
double GetDuration();
// Packet handling methods:
-// HX_RESULT InitForReading(CRIFFReader* pReader);
HX_RESULT CAVIStream::InitForReading(IUnknown* pContext, IHXFileObject* pFile);
BOOL ReadInitialized();
@@ -118,6 +125,21 @@
// chunk
void GetNextSlice();
+#ifdef HELIX_FEATURE_AVI2
+ // We always have 1 stdindex loaded in the memory hence we always return
+ // FALSE for this function.
+ // Can be optimised by not loading complete stdindex and only part of it and \
implemenet + // this function in true sense.
+ HXBOOL CanLoadSlice()
+ {
+ return FALSE;
+ }
+ HXBOOL IsTargetChunkLoaded(UINT32 ulTargetChunk);
+#endif
+
+ HXBOOL IsKeyChunk(UINT16 usStream, UINT32 ulTargetKeyChunk);
+ UINT32 GetChunkLength(UINT16 usStream, UINT32 ulTargetKeyChunk);
+
BOOL CanPrefetchSlice();
UINT32 PeekPrefetchTime(); // Next unloaded slice
UINT32 GetMaxChunkRead();
@@ -204,6 +226,71 @@
INT16 sRight;
} m_header;
+
+#ifdef HELIX_FEATURE_AVI2
+/////////////////////////////////////////////////////////////////////////
+/*
+ AVI2.0 ODML index can have either Super index, standard index or field index.
+ The base index has following structure which takes either of the above mentioned
+ form based on Index type.
+
+ struct AviBaseIndex
+ {
+ UINT16 usLongsPerEntry; // size of each entry in aIndex array
+ BYTE ucIndexSubType; // future use. must be 0
+ BYTE ucIndexType; // one of AVI_INDEX_* codes
+ UINT32 ulNEntriesInUse; // index of first unused member in aIndex \
array + UINT32 ulChunkId; // fcc of what is indexed
+ UINT32 ulReserved[3]; // meaning differs for each index
+ struct AviBaseIndexEntry
+ {
+ UINT32 adw[20];
+ }aIndex[];
+
+ };
+ Support is provided for Super index and standard index.
+*/
+/////////////////////////////////////////////////////////////////////////
+
+struct AviStdIndexEntry
+{
+ UINT32 ulOffset; // llBaseOffset + this is absolute file offset
+ UINT32 ulSize; // bit 31 is set if this is NOT a keyframe
+};
+
+struct AviStdIndex
+{
+ UINT16 usLongsPerEntry; // must be sizeof(aIndex[0])/sizeof(DWORD)
+ BYTE ucIndexSubType; // must be 0
+ BYTE ucIndexType; // must be AVI_INDEX_OF_CHUNKS
+ UINT32 ulNEntriesInUse;
+ UINT32 ulChunkId; // ’##dc’ or ’##db’ or ’##wb’ etc..
+ UINT64 llBaseOffset; // all ulOffsets in aIndex array are relative to this
+ UINT32 ulReserved3; // must be 0
+ AviStdIndexEntry aIndex[STDIDX_ENTRIES_READ_AT_A_TIME];
+};
+
+struct AviSuperIndexEntry
+{
+ UINT64 llOffset;
+ UINT32 ulSize;
+ UINT32 ulDuration;
+};
+
+struct AviSuperIndex
+{
+ UINT16 usLongsPerEntry;
+ BYTE ucIndexSubType; // must be 0
+ BYTE ucIndexType; // must be AVI_INDEX_OF_INDEXES
+ UINT32 ulNEntriesInUse; // number of entries in aIndex array that are used
+ UINT32 ulChunkId; // ’##dc’ or ’##db’ or ’##wb’, etc
+ UINT32 ulReserved[3];
+ AviSuperIndexEntry aIndex[MAX_INDEX_CHUNKS]; // Can be optimised. \
Theoritically it means +}; // we can read a \
file max upto MAX_INDEX_CHUNKS. +
+#endif
+
+
double m_fChunksPerSecond;
double m_fSamplesPerSecond;
UCHAR* m_pFormat; /* BitmapInfo for video stream,
@@ -272,6 +359,12 @@
, eChunkFind
, eChunkRead
, eReady
+#ifdef HELIX_FEATURE_AVI2
+ ,eSuperIndexSeek
+ ,eSuperIndexRead
+ ,eStandardIndexEntryRead
+ ,eSeekPending
+#endif
} m_state;
@@ -311,6 +404,23 @@
BOOL m_bRead; // All data (chunks) read. Reset on seek.
BOOL m_bDiscardPendingIO;
+ UINT32 m_ulMaxByteDeflict;
+ UINT32 m_ulMaxChunkSize; // maximum chunk size seen so far.
+ UINT32 m_ulAvgChunkSize;
+
+#ifdef HELIX_FEATURE_AVI2
+ AviStdIndex* m_pStdIndex ;
+ AviSuperIndex* m_pSuperIndex;
+
+ // extra variables for ODML handling
+ HXBOOL m_bHasAviOdmlIndex;
+ UINT32 m_ulTotalNumberOfChunks; // specific to this particular stream
+ UINT64 m_ullBytesTotal;
+ UINT32 m_ulSizeOfCurrentChunk;
+ UINT32 m_ulCurrentSuperIndexEntry;
+ UINT32 m_ulTargetSeekTime;
+#endif
+
IUnknown* m_pContext;
IHXCommonClassFactory* m_pCommonClassFactory;
Index: minifileobj.cpp
===================================================================
RCS file: /cvsroot/filesystem/local/mini/minifileobj.cpp,v
retrieving revision 1.39.14.1
diff -w -u -b -r1.39.14.1 minifileobj.cpp
--- minifileobj.cpp 15 Oct 2009 19:07:18 -0000 1.39.14.1
+++ minifileobj.cpp 2 Dec 2009 16:51:14 -0000
@@ -80,7 +80,7 @@
#include "ihxmmfdatasource.h"
#endif
-#define MAX_READ_SIZE 0x000FFFFF
+#define MAX_READ_SIZE 0x0FFFFFFF
#define D_MINI_FO 0x1000000
// CHXMiniFileObject Class Methods
Index: helix-client-s60-52-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-s60-52-common.pfi,v
retrieving revision 1.10
diff -w -u -b -r1.10 helix-client-s60-52-common.pfi
--- helix-client-s60-52-common.pfi 17 Nov 2009 14:53:18 -0000 1.10
+++ helix-client-s60-52-common.pfi 2 Dec 2009 16:52:37 -0000
@@ -64,6 +64,7 @@
project.AddDefines('HELIX_FEATURE_HTTP_MEMCACHE')
#project.AddDefines('HELIX_FEATURE_SYMBIAN_ADVANCED_SECURE_OUTPUT')
project.AddDefines('HELIX_FEATURE_64_BIT_FILE_SUPPORT')
+project.AddDefines('HELIX_FEATURE_AVI2')
project.AddDefines('HELIX_CONFIG_SYMBIAN_HEADER_STRUCTURE_CHANGE')
project.AddDefines('HELIX_FEATURE_SYMBIAN_MDF_AUDIO_DOLBY_DIGITAL')
project.AddDefines('HELIX_CONFIG_SYMBIAN_USE_STDAPIS')
Index: minifileobj.cpp
===================================================================
RCS file: /cvsroot/filesystem/local/mini/minifileobj.cpp,v
retrieving revision 1.39.14.1
retrieving revision 1.39.14.2
diff -u -d -r1.39.14.1 -r1.39.14.2
--- minifileobj.cpp 15 Oct 2009 19:07:18 -0000 1.39.14.1
+++ minifileobj.cpp 2 Dec 2009 17:00:18 -0000 1.39.14.2
@@ -80,7 +80,7 @@
#include "ihxmmfdatasource.h"
#endif
-#define MAX_READ_SIZE 0x000FFFFF
+#define MAX_READ_SIZE 0x0FFFFFFF
#define D_MINI_FO 0x1000000
// CHXMiniFileObject Class Methods
_______________________________________________
Filesystem-cvs mailing list
Filesystem-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/filesystem-cvs
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic