[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