[prev in list] [next in list] [prev in thread] [next in thread]
List: helix-datatype-cvs
Subject: [Datatype-cvs] wm/fileformat asf_file_format_file.cpp, 1.22.4.6,
From: shashikm () helixcommunity ! org
Date: 2010-06-25 17:28:47
Message-ID: 201006251729.o5PHTXAW009156 () mailer ! progressive-comp ! com
[Download RAW message or body]
Update of /cvsroot/datatype/wm/fileformat
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv20203
Modified Files:
Tag: hxclient_4_2_0_brizo
asf_file_format_file.cpp
Log Message:
"Nokia submits this code under the terms of a commercial contribution agreement with \
RealNetworks, and I am authorized to contribute this code under said agreement."
Modified by: ext-anugrah.2.kashari@nokia.com
Reviewed by: Shy.Ward@nokia.com; girish.shetty@nokia.com, qluo@real.com
TSW Id: ESLM-869LV3
Date: 06/23/2010
Project: SymbianMmf_wm
Synopsis: Memory full error when seeking forward on a long corrupted wmv file
Overview: For this content, when user seeks after playback has begun, "Memory Full" \
error message in shown and playback closes. Attached video file does not have index \
object so seek is not possible. Current implementation of ASF file format is that if \
index object is not available then seek to first packet and start sending packets \
from there (see the else case for m_ulState == \
kStateSeekIndexObjectHeaderReadDonePending in CASFFileFormatFile::ReadDone() ). So \
after seek ASF FF starts sending packet from very first payload and HXFileSource \
keeps appending them to the event list. But helix core does not process these events \
(or packets) as they are too old, and event-list keeps growing and helix finally runs \
out of memory.
Fix: ASF FF looks for index object and load index object during first seek. If index \
object is not present then seek is not possible. This information need to be passed \
in stream header. So changes code to look for index object during header parsing and \
set "NonSeekable" flag accordingly.
Files modified & changes:
/datatype/wm/fileformat/asf_file_format_file.cpp
/datatype/wm/fileformat/pub/asf_file_format_file.h
Image Size and Heap Use impact: No major impact
Module Release testing (STIF) : Done
Test case(s) Added : No
Memory leak check performed : Passed, No additional leaks introduced.
Platforms and Profiles Build Verified: helix-client-s60-52-mmf-mdf-dsp
Platforms and Profiles Functionality verified: armv5
Branch: 210CayS, 420Bizo and HEAD
Diff: Attached.
Index: asf_file_format_file.cpp
===================================================================
RCS file: /cvsroot/datatype/wm/fileformat/asf_file_format_file.cpp,v
retrieving revision 1.22.4.6
retrieving revision 1.22.4.7
diff -u -d -r1.22.4.6 -r1.22.4.7
--- asf_file_format_file.cpp 8 Jun 2010 17:24:25 -0000 1.22.4.6
+++ asf_file_format_file.cpp 25 Jun 2010 17:28:45 -0000 1.22.4.7
@@ -143,6 +143,10 @@
m_pWM2StreamPropertiesMap = NULL;
m_pWM2ExtStreamPropertiesMap = NULL;
m_ulLastPacketSentTS = 0;
+
+ m_bIsContentSeekable = TRUE;
+ m_bReadyToSentHeader = FALSE;
+
memset(m_pucWM2HXStreamNumberMap, HX_INVALID_STREAM_NUMBER, \
HX_NUM_STREAM_MAP_ENTRIES);
memset(m_pucWM2HXSubStreamIndexMap, HX_INVALID_STREAM_NUMBER, \
HX_NUM_STREAM_MAP_ENTRIES); }
@@ -629,108 +633,114 @@
HXBOOL bSeekingToPacket = FALSE;
UINT32 ulActualSeekTime = 0;
UINT64 ullFileOffset = 0;
- retVal = SearchIndexTable(ulDesiredPresTime, FALSE, ulActualSeekTime, \
ullFileOffset);
- if (SUCCEEDED(retVal))
- {
- HXLOGL3(HXLOG_ASFF, "\tOn-the-fly table provided seek offset \
(time=%lu,offset=%I64u)",
- ulActualSeekTime, ullFileOffset);
- // We will be seeking right to an ASF packet
- // (as opposed to seeking to an index table for
- // further reading)
- bSeekingToPacket = TRUE;
- }
- else
+
+ // Seek is allowed if the file is seekable
+ if(m_bIsContentSeekable)
{
- // We could not determine the seek location from the
- // on-the-fly seek table. Therefore, we should try
- // to look it up from an index ASF object at the
- // end of the file. However, first we must determine
- // if there actually IS an Index object (or a Simple
- // Index object) at the end of the file. We know
- // there will be an Index object if there is
- // an index parameters object in the header.
- // However, if we have a linear file system (i.e. -
- // an HTTP 1.0 filesystem that hasn't finished
- // downloading the file), then we don't want to
- // seek to the end of the file.
- if (CanUseIndexObjectsForSeeking() && !bLinearFileSystem)
+ retVal = SearchIndexTable(ulDesiredPresTime, FALSE, ulActualSeekTime, \
ullFileOffset); + if (SUCCEEDED(retVal))
{
- // We do have index objects (either an Index Object or
- // a Simple Index Object) at the end of the file
- // that we can use. So we need to seek to just past
- // the end of the ASF Data Object.
- UINT64 ullOffset = m_pDataObject->m_ullFileOffset +
- m_pDataObject->m_ullASFObjectSize;
- // Assume for now the files are less than 4GB
-#ifdef HELIX_FEATURE_64_BIT_FILE_SUPPORT
- HX_ASSERT(ullOffset <= 0xFFFFFFFFFFFFFFFF);
-#else
- HX_ASSERT(ullOffset <= 0xFFFFFFFF);
-#endif
- // Assign the offset we will be seeking to
- ullFileOffset = ullOffset;
- // Log a message saying we are seeking to the end of the file
- HXLOGL3(HXLOG_ASFF, "\tSeeking to index objects starting at file offset \
%I64u", ullFileOffset);
- // Initialize the index of simple index objects
- m_ulSimpleIndexOrderIndex = 0;
- // We are not seeking to a packet but rather a index
- bSeekingToPacket = FALSE;
- // Clear the return value
- retVal = HXR_OK;
+ HXLOGL3(HXLOG_ASFF, "\tOn-the-fly table provided seek offset \
(time=%lu,offset=%I64u)", + ulActualSeekTime, ullFileOffset);
+ // We will be seeking right to an ASF packet
+ // (as opposed to seeking to an index table for
+ // further reading)
+ bSeekingToPacket = TRUE;
}
else
{
- // We either don't have an index or we can' use it
- // due to a linear filesystem. See if we can
- // estimate the seek time.
- //
- // Are we a single-stream audio file?
- if (IsSingleStreamAudioFile())
+ // We could not determine the seek location from the
+ // on-the-fly seek table. Therefore, we should try
+ // to look it up from an index ASF object at the
+ // end of the file. However, first we must determine
+ // if there actually IS an Index object (or a Simple
+ // Index object) at the end of the file. We know
+ // there will be an Index object if there is
+ // an index parameters object in the header.
+ // However, if we have a linear file system (i.e. -
+ // an HTTP 1.0 filesystem that hasn't finished
+ // downloading the file), then we don't want to
+ // seek to the end of the file.
+ if (CanUseIndexObjectsForSeeking() && !bLinearFileSystem)
{
- // Single-stream audio files often don't have index
- // objects since audio is constant bitrate,
- // packet sizes are fixed, and there are no
- // keyframes. Therefore, it is possible
- // to do a very good estimate of where to seek
- // to just based on duration, number of packets,
- // and the requested seek time.
- retVal = EstimateSeekTime(ulOffset, ullFileOffset);
- if (SUCCEEDED(retVal))
- {
- // Log a message saying we are seeking to the end of the file
- HXLOGL3(HXLOG_ASFF, "\tSingle-stream audio file, so using seek \
estimate of %I64u", ullFileOffset);
- }
+ // We do have index objects (either an Index Object or
+ // a Simple Index Object) at the end of the file
+ // that we can use. So we need to seek to just past
+ // the end of the ASF Data Object.
+ UINT64 ullOffset = m_pDataObject->m_ullFileOffset +
+ m_pDataObject->m_ullASFObjectSize;
+
+ // Assume for now the files are less than 4GB
+ #ifdef HELIX_FEATURE_64_BIT_FILE_SUPPORT
+ HX_ASSERT(ullOffset <= 0xFFFFFFFFFFFFFFFF);
+ #else
+ HX_ASSERT(ullOffset <= 0xFFFFFFFF);
+ #endif
+ // Assign the offset we will be seeking to
+ ullFileOffset = ullOffset;
+ // Log a message saying we are seeking to the end of the file
+ HXLOGL3(HXLOG_ASFF, "\tSeeking to index objects starting at file \
offset %I64u", ullFileOffset); + // Initialize the index of simple \
index objects + m_ulSimpleIndexOrderIndex = 0;
+ // We are not seeking to a packet but rather a index
+ bSeekingToPacket = FALSE;
+ // Clear the return value
+ retVal = HXR_OK;
}
- // Do we *still* not know where to seek?
- if (FAILED(retVal))
+ else
{
- // Try getting the latest value from the on-the-fly index
- // table (the TRUE forces the table to give us the
- // latest values). If nothing else, we can start seeking from the
- // last known packet offset
- retVal = SearchIndexTable(ulDesiredPresTime, TRUE, ulActualSeekTime, \
ullFileOffset);
- if (SUCCEEDED(retVal))
+ // We either don't have an index or we can' use it
+ // due to a linear filesystem. See if we can
+ // estimate the seek time.
+ //
+ // Are we a single-stream audio file?
+ if (IsSingleStreamAudioFile())
{
- // Log a message saying we are starting from the last known \
on-the-fly entry
- HXLOGL3(HXLOG_ASFF, "\tStarting at last known on-the-fly index \
table entry: (time=%lu,offset=%I64u)",
- ulActualSeekTime, ullFileOffset);
+ // Single-stream audio files often don't have index
+ // objects since audio is constant bitrate,
+ // packet sizes are fixed, and there are no
+ // keyframes. Therefore, it is possible
+ // to do a very good estimate of where to seek
+ // to just based on duration, number of packets,
+ // and the requested seek time.
+ retVal = EstimateSeekTime(ulOffset, ullFileOffset);
+ if (SUCCEEDED(retVal))
+ {
+ // Log a message saying we are seeking to the end of the \
file + HXLOGL3(HXLOG_ASFF, "\tSingle-stream audio file, so \
using seek estimate of %I64u", ullFileOffset); + }
}
- else
+ // Do we *still* not know where to seek?
+ if (FAILED(retVal))
{
- // Yikes - no latest time. Well, the best we can
- // do then is to start back at the first packet.
- ullFileOffset = m_ullFirstASFPacketFileOffset;
- // Log a message saying we are starting from the first packet
- HXLOGL3(HXLOG_ASFF, "\tStarting from first ASF packet at offset \
%I64u", ullFileOffset);
- // Clear the return value
- retVal = HXR_OK;
+ // Try getting the latest value from the on-the-fly index
+ // table (the TRUE forces the table to give us the
+ // latest values). If nothing else, we can start seeking from \
the + // last known packet offset
+ retVal = SearchIndexTable(ulDesiredPresTime, TRUE, \
ulActualSeekTime, ullFileOffset); + if (SUCCEEDED(retVal))
+ {
+ // Log a message saying we are starting from the last known \
on-the-fly entry + HXLOGL3(HXLOG_ASFF, "\tStarting at last \
known on-the-fly index table entry: (time=%lu,offset=%I64u)", + \
ulActualSeekTime, ullFileOffset); + }
+ else
+ {
+ // Yikes - no latest time. Well, the best we can \
+ // do then is to start back at the first packet.
+ ullFileOffset = m_ullFirstASFPacketFileOffset;
+ // Log a message saying we are starting from the first \
packet + HXLOGL3(HXLOG_ASFF, "\tStarting from first ASF packet \
at offset %I64u", ullFileOffset); + // Clear the return value
+ retVal = HXR_OK;
+ }
}
+ // In all of the cases above, we are seeking to a packet
+ bSeekingToPacket = TRUE;
}
- // In all of the cases above, we are seeking to a packet
- bSeekingToPacket = TRUE;
}
}
-
+
// Do we have a valid file offset to seek to?
if (SUCCEEDED(retVal))
{
@@ -768,6 +778,8 @@
}
else
{
+ HXLOGL2(HXLOG_ASFF, "\tSeek failed error code %x", retVal);
+
// We failed to find any file offset to seek to
// so call back to the format response with failure
m_pFormatResponse->SeekDone(retVal);
@@ -947,8 +959,16 @@
m_ullFirstASFPacketFileOffset = m_ullFileOffset;
// We just read the data object header, so we have read
// the end of the header object. So we can create
- // the file header
- retVal = SendFileHeader();
+ // the file header. We set m_bReadyToSentHeader here and \
will send + // header data once are done looking for index \
objects + m_bReadyToSentHeader = TRUE;
+ // Compute the next object offset. Normally this will be \
index object + m_ullSeekOffsetRequested = ullFileOffset + \
INT64_TO_UINT32(m_ullASFObjectSize); + // Set the state
+ m_ulState = kStateGFHASFIndexObjectSeekDonePending;
+ // Seek just past the end of the ASF object
+ DoSeek(m_ullSeekOffsetRequested);
+
}
else
{
@@ -992,6 +1012,64 @@
retVal = HXR_OK;
}
}
+ else if (m_ulState == kStateGFHASFIndexObjectHeaderReadDonePending)
+ {
+ if (SUCCEEDED(status))
+ {
+ // Parse the ASF object header
+ retVal = UnpackASFObjectHeader(pBuffer->GetBuffer(), pBuffer->GetSize(), \
&m_eASFObjectType, &m_ullASFObjectSize); + if (SUCCEEDED(retVal))
+ {
+ // Make sure this is either an Index Object or Simple Index object
+ if (m_eASFObjectType == HX_ASF_Simple_Index_Object || \
m_eASFObjectType == HX_ASF_Index_Object || + \
(INT64_TO_UINT32(m_ullASFObjectSize) == 0) ) + {
+ if(m_bReadyToSentHeader)
+ {
+ m_bReadyToSentHeader = FALSE;
+ m_bIsContentSeekable = (INT64_TO_UINT32(m_ullASFObjectSize) \
!= 0) ? TRUE : FALSE ; + retVal = SendFileHeader();
+ // Reset offset to start of packet;
+ m_ullSeekOffsetRequested = m_ullFirstASFPacketFileOffset;
+ // Set the state saying this is the final seek prior to \
calling SeekDone() + m_ulState = \
kStateGFHASFIndexObjectFinalSeekDonePending; + // Now seek the \
file object to the first ASF packet + \
DoSeek(m_ullSeekOffsetRequested); + }
+ }
+ else
+ {
+ // This is either another type of index (Media Object Index \
object + // or Timecode Index object) which we currently don't \
use, or it's + // some kind of custom object which we don't need. \
Either way, skip it. + //
+ // Compute the next object offset
+ m_ullSeekOffsetRequested = m_ullFileOffset - pBuffer->GetSize() \
+ INT64_TO_UINT32(m_ullASFObjectSize); + // Set the state
+ m_ulState = kStateGFHASFIndexObjectSeekDonePending;
+ // Seek just past the end of the ASF object
+ DoSeek(m_ullSeekOffsetRequested);
+ }
+ }
+ }
+ else
+ {
+ if(m_bReadyToSentHeader)
+ {
+ m_bReadyToSentHeader = FALSE;
+ m_bIsContentSeekable = FALSE;
+ retVal = SendFileHeader();
+ // Reset offset to start of packet;
+ m_ullSeekOffsetRequested = m_ullFirstASFPacketFileOffset;
+ // Set the state saying this is the final seek prior to calling \
SeekDone() + m_ulState = kStateGFHASFIndexObjectFinalSeekDonePending;
+ // Now seek the file object to the first ASF packet
+ DoSeek(m_ullSeekOffsetRequested);
+ }
+
+ }
+
+ }
else if (m_ulState == kStateGPReadDonePending)
{
// Did the read succeed?
@@ -1317,6 +1395,34 @@
// Clear the return value
retVal = HXR_OK;
}
+ else if (m_ulState == kStateGFHASFIndexObjectSeekDonePending)
+ {
+ if (SUCCEEDED(status))
+ {
+ // Set the state
+ m_ulState = kStateGFHASFIndexObjectHeaderReadDonePending;
+ // Read HX_ASF_OBJECT_HEADER_SIZE bytes
+ m_pFileObject->Read(HX_ASF_OBJECT_HEADER_SIZE);
+ }
+ else
+ {
+ // Set the state
+ m_ulState = kStateReady;
+ // Fail out
+ m_pFormatResponse->FileHeaderReady(status, NULL);
+ }
+ // Clear the return value
+ retVal = HXR_OK;
+ }
+ else if (m_ulState == kStateGFHASFIndexObjectFinalSeekDonePending)
+ {
+ // This will be called after we are done looking for index object and
+ // this willl reset file offset to the first packet
+ // Set the state
+ m_ulState = kStateReady;
+ // Clear the return value
+ retVal = HXR_OK;
+ }
else if (m_ulState == kStateSeekFinalSeekDonePending)
{
// Set the state
@@ -1540,6 +1646,16 @@
pHdr->SetPropertyULONG32("Duration", ulDuration);
// Set the title/author/copyright info
SetTACInfo(pHdr);
+
+ if(IsSingleStreamAudioFile())
+ {
+ m_bIsContentSeekable = TRUE;
+ }
+
+ pHdr->SetPropertyULONG32("NonSeekable",!m_bIsContentSeekable);
+
+ HXLOGL2(HXLOG_ASFF, "ASF file header seekable %d \
",m_bIsContentSeekable); +
// XXXMEH - TODO: Implement "AcceptMetaInfo" support here
#if defined(HELIX_FEATURE_DRM)
_______________________________________________
Datatype-cvs mailing list
Datatype-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/datatype-cvs
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic