[Helix-client-dev] CR : fix conflict, when two player using the same fd to access different content

yuan <[email protected]> Fri, 21 Oct 2011 13:11:14 +0800
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <[email protected]>
Modified by: [email protected]

Date: 10/21/2011

Project: RealPlayer for Android Smartphones

Bug Number: 13992


Synopsis: cannot play some sound in a game

 
Overview:

In that game, two audio files are stored in a apk.

Two player are created, and setDataSource with the same fd, and
different offsets and lengths.

In our implementation of using fd to access file,  read and lseek64 are
used.

When that two player play at the same time, they conflicts because they
access share resource.


1. To remove that conflict,  seek operation is deferred until read is
needed.

2. Add boundary check, because when using fd to access content, the end
of content does not mean end of file always.
    that depends on type of file.




Files Added:

None


Files Modified:

/common/fileio/fdbufdataf.cpp
/common/fileio/fdbufdataf.h



Image Size and Heap Use impact (Client -Only): none


Distribution Libraries Affected: none 


Platforms and Profiles Affected:

        Platform: android-2.3-arm-smdk_c110
        Profile: helix-client-android-LePhoneTD-C110


Platforms and Profiles Build Verified:

        Platform: android-2.3-arm-smdk_c110
        Profile: helix-client-android-LePhoneTD-C110

 

Platforms and Profiles Functionality verified:

        Platform: android-2.3-arm-smdk_c110
        Profile: helix-client-android-LePhoneTD-C110

 

Branch: 361_atlas

 

Copyright assignment: I am a RealNetworks employee



Thanks

Yuan Zhang

_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
fileio.diff (text/x-patch, 5.7 KB)
? fileio/Makefile
? fileio/Umakefil.upp
? fileio/android-dbg
? fileio/dbg
? fileio/rel
? fileio/ribosome_logs
Index: fileio/fdbufdataf.cpp
===================================================================
RCS file: /cvsroot/common/fileio/fdbufdataf.cpp,v
retrieving revision 1.1.2.6
diff -u -w -r1.1.2.6 fdbufdataf.cpp
--- fileio/fdbufdataf.cpp	15 Apr 2011 07:13:04 -0000	1.1.2.6
+++ fileio/fdbufdataf.cpp	21 Oct 2011 04:05:39 -0000
@@ -69,7 +69,6 @@
 
 #include "hxurl.h"
 
-
 /*
  *  IUnknown methods
  */
@@ -121,6 +120,7 @@
     , m_nMyFD(-1)
     , m_ulBaseOffset(0)
     , m_ulLength(0)
+    , m_ulFileOffset(0)
 {
     HX_ADDREF(m_pContext);
     if (CreateBufferCCF(m_pFilename, m_pContext) != HXR_OK)
@@ -256,9 +256,7 @@
 	
 	if (m_pFile)
 	{
-
 		Seek(0, SEEK_SET);
-
 	    return HXR_OK;
 	}
 	else
@@ -384,26 +382,25 @@
     if (m_pFile)
     {
 	m_ulLastError = HXR_OK;       
-        //Always add m_ulBaseOffset in Seek and 
-        //always subtract m_ulBaseOffset  in Tell 
-        //to completely hide the fact m_ulBaseOffset exists.
-        offset += m_ulBaseOffset;
-#ifdef HELIX_HAS_LARGE_FILE_SUPPORT
-#ifdef ANDROID
-        off64_t seekRet = lseek64(m_nMyFD, (off64_t)offset, fromWhere);
-#else
-        int seekRet = fseeko(m_pFile, offset, fromWhere);
-#endif
-#else
-        int seekRet = fseek(m_pFile, offset, fromWhere);
-#endif
-        if (seekRet == -1)
+
+        switch ( fromWhere )
 	{
-	    m_ulLastError = errno;
-	    return HXR_INVALID_FILE;
+            case SEEK_SET:
+                m_ulFileOffset =  m_ulBaseOffset+offset;
+                break;
+            case SEEK_END:
+                m_ulFileOffset = m_ulBaseOffset + m_ulLength - offset;
+                break;
+            case SEEK_CUR:
+                m_ulFileOffset += offset;
+                break;
+            default:
+                ;
 	}
+
 	return HXR_OK;
     }
+    else
     return HXR_INVALID_FILE;
 }
 
@@ -413,23 +410,12 @@
     m_ulLastError = (UINT32)HXR_FAIL;
     if (m_pFile)
     {
-#ifdef HELIX_HAS_LARGE_FILE_SUPPORT
-#ifdef ANDROID
-        off64_t tellRet = lseek64(m_nMyFD, 0, SEEK_CUR);
-#else
-        // The fseeko() is identical to fseek, except that the offset is of type off_t instead of long
-        // which "#define _FILE_OFFSET_BITS 64" will turn off_t into a 64-bit type.
-        int tellRet = ftello(m_pFile);
-#endif
-#else
-        int tellRet = ftell(m_pFile);
-#endif
-	if (tellRet != -1)
+        ULONG32 tellRet = m_ulFileOffset;
 	{
             tellRet -= m_ulBaseOffset;
 	    m_ulLastError = HXR_OK;       
 	}
-        return (ULONG32) tellRet;
+        return tellRet;
     }
     return -1;
 }
@@ -449,28 +435,52 @@
 	}
 	else
 	{
-	    m_ulLastError = (UINT32)HXR_OUTOFMEMORY;
 	    CreateBufferCCF(pBuf, m_pContext);
     	    bNewBuffer = TRUE;
 	}
 
 	if (pBuf)
 	{
-	    m_ulLastError = pBuf->SetSize(count);
+            pBuf->SetSize(count);
+        }
+        else
+        {
+            m_ulLastError = (UINT32)HXR_OUTOFMEMORY;
 	}
 	
 	if (m_ulLastError == HXR_OK)
 	{
-	    Tell();
+            if ( IsOutOfRange( m_ulFileOffset ) )
+            {
+                pBuf->SetSize(0);
+                return 0;
+            }
+            else
+            {
+                UINT32 remain = m_ulBaseOffset + m_ulLength - m_ulFileOffset;
+                if ( remain < count ) count = remain;
+
+            }
 	}
 
 	if (m_ulLastError == HXR_OK)
 	{
+        UINT32 offset = m_ulFileOffset;
+        int fromWhere = SEEK_SET;
 #ifdef HELIX_HAS_LARGE_FILE_SUPPORT
+#ifdef ANDROID
+        off64_t seekRet = lseek64(m_nMyFD, (off64_t)offset, fromWhere);
             ncnt = read(m_nMyFD, (void *)pBuf->GetBuffer(), count);
 #else
+        int seekRet = fseeko(m_pFile, offset, fromWhere);
             ncnt = fread((void *)pBuf->GetBuffer(), sizeof(char), count, m_pFile);
 #endif
+#else
+        int seekRet = fseek(m_pFile, offset, fromWhere);
+        ncnt = fread((void *)pBuf->GetBuffer(), sizeof(char), count, m_pFile);
+#endif
+        if ( ncnt ) m_ulFileOffset += ncnt;
+
 	    if (ncnt  < (int)count)
 	    {
 		m_ulLastError = ferror(m_pFile) ? HXR_FAIL : HXR_OK;
@@ -504,15 +514,27 @@
     {
 	m_ulLastError = HXR_OK;
 
+    UINT32 offset = m_ulFileOffset;
+    int fromWhere = SEEK_SET;
 #ifdef HELIX_HAS_LARGE_FILE_SUPPORT
+#ifdef ANDROID
+        off64_t seekRet = lseek64(m_nMyFD, (off64_t)offset, fromWhere);
         ncnt = write(m_nMyFD, (void *)pBuf->GetBuffer(), pBuf->GetSize());
 #else
+        int seekRet = fseeko(m_pFile, offset, fromWhere);
+        ncnt = fwrite((void *)pBuf->GetBuffer(), sizeof(char), pBuf->GetSize(), m_pFile);
+#endif
+#else
+        int seekRet = fseek(m_pFile, offset, fromWhere);
         ncnt = fwrite((void *)pBuf->GetBuffer(), sizeof(char), pBuf->GetSize(), m_pFile);
 #endif
+
 	if (ncnt < (int)(pBuf->GetSize()))
 	{
 	    m_ulLastError = (UINT32)HXR_FAIL;
 	}
+        else
+        m_ulFileOffset += ncnt;
     }
     return (ULONG32)ncnt;
 }
@@ -644,3 +666,14 @@
     pRequest = NULL;
     return HXR_NOTIMPL;
 }
+
+HXBOOL
+FDBufferedDataFile::IsOutOfRange( UINT32 ulOffset )
+{
+    HXBOOL ret = FALSE;
+    if (  ulOffset >= (m_ulBaseOffset + m_ulLength ) || ulOffset < m_ulBaseOffset )
+        ret = TRUE;
+
+    return ret;
+}
+
Index: fileio/fdbufdataf.h
===================================================================
RCS file: /cvsroot/common/fileio/fdbufdataf.h,v
retrieving revision 1.1.2.1
diff -u -w -r1.1.2.1 fdbufdataf.h
--- fileio/fdbufdataf.h	16 Nov 2009 19:52:52 -0000	1.1.2.1
+++ fileio/fdbufdataf.h	21 Oct 2011 04:05:40 -0000
@@ -108,6 +108,9 @@
     int					m_nMyFD;
     UINT32				m_ulBaseOffset;
     UINT32				m_ulLength;
+    UINT32              m_ulFileOffset;
+private:
+    HXBOOL              IsOutOfRange( UINT32 ulOffset );
 };
 
 #endif /* _FDBUFFERED_DATA_FILE_H_ */