AssetLoadState OgreMeshAsset::DeserializeFromData(const u8 *data_, size_t numBytes)
{
PROFILE(OgreMeshAsset_LoadFromFileInMemory);
assert(data_);
if (!data_)
return ASSET_LOAD_FAILED;
// Force an unload of this data first.
Unload();
if (OGRE_THREAD_SUPPORT != 0)
{
// We can only do threaded loading from disk, and not any disk location but only from asset cache.
// local:// refs will return empty string here and those will fall back to the non-threaded loading.
// Do not change this to do DiskCache() as that directory for local:// refs will not be a known resource location for ogre.
QString cacheDiskSource = assetAPI->GetAssetCache()->GetDiskSource(QUrl(Name()));
if (!cacheDiskSource.isEmpty())
{
QFileInfo fileInfo(cacheDiskSource);
std::string sanitatedAssetRef = fileInfo.fileName().toStdString();
loadTicket_ = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(),
sanitatedAssetRef, OgreRenderer::OgreRenderingModule::CACHE_RESOURCE_GROUP,
false, 0, 0, this);
return ASSET_LOAD_PROCESSING;
}
}
if (ogreMesh.isNull())
{
ogreMesh = Ogre::MeshManager::getSingleton().createManual(
OgreRenderer::SanitateAssetIdForOgre(this->Name().toStdString()), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (ogreMesh.isNull())
{
LogError("Failed to create mesh " + Name().toStdString());
return ASSET_LOAD_FAILED;
}
ogreMesh->setAutoBuildEdgeLists(false);
}
std::vector<u8> tempData(data_, data_ + numBytes);
#include "DisableMemoryLeakCheck.h"
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)&tempData[0], numBytes, false));
#include "EnableMemoryLeakCheck.h"
Ogre::MeshSerializer serializer;
serializer.importMesh(stream, ogreMesh.getPointer()); // Note: importMesh *adds* submeshes to an existing mesh. It doesn't replace old ones.
// Generate tangents to mesh
try
{
unsigned short src, dest;
///\bug Crashes if called for a mesh that has null or zero vertices in the vertex buffer, or null or zero indices in the index buffer.
if (!ogreMesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src, dest))
ogreMesh->buildTangentVectors(Ogre::VES_TANGENT, src, dest);
}
catch (...) {}
// Generate extremity points to submeshes, 1 should be enough
try
{
for(uint i = 0; i < ogreMesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh *smesh = ogreMesh->getSubMesh(i);
if (smesh)
smesh->generateExtremes(1);
}
}
catch (...) {}
try
{
// Assign default materials that won't complain
SetDefaultMaterial();
// Set asset references the mesh has
//ResetReferences();
}
catch (Ogre::Exception &e)
{
LogError("Failed to create mesh " + this->Name().toStdString() + ": " + std::string(e.what()));
Unload();
return ASSET_LOAD_FAILED;
}
//internal_name_ = SanitateAssetIdForOgre(id_);
LogDebug("Ogre mesh " + this->Name().toStdString() + " created");
return ASSET_LOAD_SUCCESFULL;
}
//FIXME: this older code version is only for backward compatibility with dependent classes.
// proper fix is to change code of all classes that depend on PidInfo2 in favour of CPidTable!
bool CPmtParser::DecodePmt(CSection sections, int& pcr_pid, bool& hasCaDescriptor, vector<PidInfo2>& pidInfos)
{
byte* section=sections.Data;
int sectionLen=sections.section_length;
int table_id = sections.table_id;
if (table_id!=2) return false;
if (m_serviceId!=-1)
if (sections.table_id_extension!=m_serviceId) return false;
int section_syntax_indicator = (section[1]>>7) & 1;
int section_length = ((section[1]& 0xF)<<8) + section[2];
int program_number = (section[3]<<8)+section[4];
int version_number = ((section[5]>>1)&0x1F);
int current_next_indicator = section[5] & 1;
int section_number = section[6];
int last_section_number = section[7];
pcr_pid=((section[8]& 0x1F)<<8)+section[9];
int program_info_length = ((section[10] & 0xF)<<8)+section[11];
int len2 = program_info_length;
int pointer = 12;
int len1 = section_length -( 9 + program_info_length +4);
int x;
// loop 1
while (len2 > 0)
{
int indicator=section[pointer];
if (indicator == 0x9) // MPEG CA descriptor, implying the service is scrambled
{
hasCaDescriptor = true;
}
int descriptorLen=section[pointer+1];
len2 -= (descriptorLen+2);
pointer += (descriptorLen+2);
}
// loop 2
int stream_type=0;
int elementary_PID=0;
int ES_info_length=0;
int audioToSet=0;
int subtitleToSet=0;
pidInfos.clear();
while (len1 > 0)
{
//if (start+pointer+4>=sectionLen+9) return ;
int curSubtitle=-1;
stream_type = section[pointer];
elementary_PID = ((section[pointer+1]&0x1F)<<8)+section[pointer+2];
ES_info_length = ((section[pointer+3] & 0xF)<<8)+section[pointer+4];
if (pointer+ES_info_length>=sectionLen)
{
LogDebug("pmt parser check 1");
return false;
}
PidInfo2 pidInfo2;
pidInfo2.fakePid=-1;
pidInfo2.elementaryPid=elementary_PID;
pidInfo2.streamType=stream_type;
pidInfo2.rawDescriptorSize=ES_info_length;
if (pidInfo2.streamType!=SERVICE_TYPE_DVB_SUBTITLES2)
pidInfo2.logicalStreamType=stream_type;
//ITV HD workaround
if (pidInfo2.streamType==SERVICE_TYPE_DVB_SUBTITLES2 && program_number==10510)
{
if (pidInfo2.logicalStreamType==0xffffffff && pidInfo2.elementaryPid==0xd49)
{
pidInfo2.streamType=SERVICE_TYPE_VIDEO_H264;
pidInfo2.logicalStreamType=SERVICE_TYPE_VIDEO_H264;
LogDebug("DecodePmt: set ITV HD video stream to H.264");
}
}
//end of workaround
// Boundary check
if(ES_info_length > sizeof(pidInfo2.rawDescriptorData))
{
LogDebug("pmt parser check 3");
return false;
}
if (pidInfo2.streamType==SERVICE_TYPE_DVB_SUBTITLES2)
pidInfo2.logicalStreamType=-1;
memset(pidInfo2.rawDescriptorData,0xFF,ES_info_length);
memcpy(pidInfo2.rawDescriptorData,§ion[pointer+5],ES_info_length);
pointer += 5;
len1 -= 5;
len2 = ES_info_length;
while (len2 > 0)
{
if (pointer+1>=sectionLen)
{
LogDebug("pmt parser check2");
//.........这里部分代码省略.........
//.........这里部分代码省略.........
((fsal_buffdesc_t *) & arg_OPEN4.claim.open_claim4_u.
file, &filename))) != CACHE_INODE_SUCCESS)
{
res_OPEN4.status = nfs4_Errno(cache_status);
return res_OPEN4.status;
}
/* Check parent */
pentry_parent = data->current_entry;
/* Parent must be a directory */
if((pentry_parent->internal_md.type != DIR_BEGINNING) &&
(pentry_parent->internal_md.type != DIR_CONTINUE))
{
/* Parent object is not a directory... */
if(pentry_parent->internal_md.type == SYMBOLIC_LINK)
res_OPEN4.status = NFS4ERR_SYMLINK;
else
res_OPEN4.status = NFS4ERR_NOTDIR;
return res_OPEN4.status;
}
/* What kind of open is it ? */
LogFullDebug(COMPONENT_NFS_V4,
" OPEN: Claim type = %d Open Type = %d Share Deny = %d Share Access = %d ",
arg_OPEN4.claim.claim,
arg_OPEN4.openhow.opentype,
arg_OPEN4.share_deny,
arg_OPEN4.share_access);
/* It this a known client id ? */
LogDebug(COMPONENT_NFS_V4,
"OPEN Client id = %llx",
(long long unsigned int)arg_OPEN4.owner.clientid);
/* Is this open_owner known ? */
convert_nfs4_owner(&arg_OPEN4.owner, &owner_name);
if(!nfs4_owner_Get_Pointer(&owner_name, &powner))
{
/* This open owner is not known yet, allocated and set up a new one */
powner = create_nfs4_owner(data->pclient,
&owner_name,
&arg_OPEN4.owner,
NULL,
1); /* NFSv4.1 specific, initial seqid is 1 */
if(powner == NULL)
{
res_OPEN4.status = NFS4ERR_SERVERFAULT;
return res_OPEN4.status;
}
}
/* Status of parent directory before the operation */
if(cache_inode_getattr(pentry_parent,
&attr_parent,
data->ht,
data->pclient,
data->pcontext,
&cache_status) != CACHE_INODE_SUCCESS)
{
res_OPEN4.status = nfs4_Errno(cache_status);
return res_OPEN4.status;
//
// OpenFile
//
// Opens the file ready for streaming
//
HRESULT FileReader::OpenFile()
{
CAutoLockFR rLock (&m_accessLock);
WCHAR *pFileName = NULL;
DWORD Tmo=14 ;
HANDLE hFileUnbuff = INVALID_HANDLE_VALUE;
//Can be used to open files in random-access mode to workaround SMB caching problems
DWORD accessModeFlags = (m_bUseRandomAccess ? FILE_FLAG_RANDOM_ACCESS : FILE_FLAG_SEQUENTIAL_SCAN);
// Is the file already opened
if (m_hFile != INVALID_HANDLE_VALUE)
{
LogDebug("FileReader::OpenFile() file already open");
return NOERROR;
}
// Has a filename been set yet
if (m_pFileName == NULL)
{
LogDebug("FileReader::OpenFile() no filename");
return ERROR_INVALID_NAME;
}
m_bIsStopping = false;
pFileName = m_pFileName;
//LogDebug("FileReader::OpenFile(), Filename: %ws.", pFileName);
do
{
if (m_bIsStopping)
return E_FAIL;
if (m_bUseDummyWrites) //enable SMB2/SMB3 file existence cache workaround
{
if ((wcsstr(pFileName, L".ts.tsbuffer") != NULL)) //timeshift file only
{
CString tempFileName = pFileName;
int replCount = tempFileName.Replace(L".ts.tsbuffer", randomStrGen(12));
if (replCount > 0)
{
//LogDebug("FileReader::OpenFile(), try to write dummy file to update SMB2 cache - %ws", tempFileName);
hFileUnbuff = ::CreateFileW(tempFileName, // The filename
(DWORD) (GENERIC_READ | GENERIC_WRITE), // File access
(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), // Share access
NULL, // Security
(DWORD) CREATE_ALWAYS, // Open flags
(DWORD) (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE), // More flags
NULL); // Template
if (hFileUnbuff != INVALID_HANDLE_VALUE)
{
char tempData[16] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
DWORD bytesWritten;
::WriteFile(hFileUnbuff, tempData, 16, &bytesWritten, NULL);
::CloseHandle(hFileUnbuff); //File is deleted on CloseHandle since FILE_FLAG_DELETE_ON_CLOSE was used
hFileUnbuff = INVALID_HANDLE_VALUE; // Invalidate the file
//LogDebug("FileReader::OpenFile(), dummy file write %d bytes to %ws", bytesWritten, tempFileName);
}
}
}
}
// do not try to open a tsbuffer file without SHARE_WRITE so skip this try if we have a buffer file
if (wcsstr(pFileName, L".ts.tsbuffer") == NULL) // not tsbuffer files
{
// Try to open the file in read-only mode (should fail for 'live' recordings)
m_hFile = ::CreateFileW(pFileName, // The filename
(DWORD) GENERIC_READ, // File access
(DWORD) FILE_SHARE_READ, // Share access
NULL, // Security
(DWORD) OPEN_EXISTING, // Open flags
(DWORD) accessModeFlags, // More flags
NULL); // Template
if (m_hFile != INVALID_HANDLE_VALUE) break ;
//This is in case file is being recorded to ('live' recordings)
m_hFile = ::CreateFileW(pFileName, // The filename
(DWORD) GENERIC_READ, // File access
(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE), // Share access
NULL, // Security
(DWORD) OPEN_EXISTING, // Open flags
(DWORD) accessModeFlags, // More flags
NULL); // Template
if (m_hFile != INVALID_HANDLE_VALUE) break ;
}
else //for tsbuffer files
{
//This is in case file is being recorded to
m_hFile = ::CreateFileW(pFileName, // The filename
(DWORD) GENERIC_READ, // File access
//.........这里部分代码省略.........
/**
*
* cache_inode_getattr: Gets the attributes for a cached entry.
*
* Gets the attributes for a cached entry. The FSAL attributes are kept in a structure when the entry
* is added to the cache.
*
* @param pentry [IN] entry to be managed.
* @param pattr [OUT] pointer to the results
* @param ht [IN] hash table used for the cache, unused in this call.
* @param pclient [INOUT] ressource allocated by the client for the nfs management.
* @param pcontext [IN] FSAL credentials
* @param pstatus [OUT] returned status.
*
* @return CACHE_INODE_SUCCESS if operation is a success \n
* @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry
*
*/
cache_inode_status_t
cache_inode_getattr(cache_entry_t * pentry,
fsal_attrib_list_t * pattr,
hash_table_t * ht, /* Unused, kept for protototype's homogeneity */
cache_inode_client_t * pclient,
fsal_op_context_t * pcontext,
cache_inode_status_t * pstatus)
{
cache_inode_status_t status;
fsal_handle_t *pfsal_handle = NULL;
fsal_status_t fsal_status;
/* sanity check */
if(pentry == NULL || pattr == NULL ||
ht == NULL || pclient == NULL || pcontext == NULL)
{
*pstatus = CACHE_INODE_INVALID_ARGUMENT;
LogDebug(COMPONENT_CACHE_INODE,
"cache_inode_getattr: returning CACHE_INODE_INVALID_ARGUMENT because of bad arg");
return *pstatus;
}
/* Set the return default to CACHE_INODE_SUCCESS */
*pstatus = CACHE_INODE_SUCCESS;
/* stats */
pclient->stat.nb_call_total += 1;
inc_func_call(pclient, CACHE_INODE_GETATTR);
/* Lock the entry */
P_w(&pentry->lock);
status = cache_inode_renew_entry(pentry, pattr, ht,
pclient, pcontext, pstatus);
if(status != CACHE_INODE_SUCCESS)
{
V_w(&pentry->lock);
inc_func_err_retryable(pclient, CACHE_INODE_GETATTR);
LogFullDebug(COMPONENT_CACHE_INODE,
"cache_inode_getattr: returning %d(%s) from cache_inode_renew_entry",
*pstatus, cache_inode_err_str(*pstatus));
return *pstatus;
}
/* RW Lock goes for writer to reader */
rw_lock_downgrade(&pentry->lock);
cache_inode_get_attributes(pentry, pattr);
if(FSAL_TEST_MASK(pattr->asked_attributes,
FSAL_ATTR_RDATTR_ERR))
{
switch (pentry->internal_md.type)
{
case REGULAR_FILE:
pfsal_handle = &pentry->object.file.handle;
break;
case SYMBOLIC_LINK:
assert(pentry->object.symlink);
pfsal_handle = &pentry->object.symlink->handle;
break;
case DIR_BEGINNING:
pfsal_handle = &pentry->object.dir_begin.handle;
break;
case DIR_CONTINUE:
/*
* lock the related dir_begin (dir begin are garbagge
* collected AFTER their related dir_cont)
* this means that if a DIR_CONTINUE exists,
* its pdir pointer is not endless
*/
P_r(&pentry->object.dir_cont.pdir_begin->lock);
pfsal_handle = &pentry->object.dir_cont.pdir_begin->object.dir_begin.handle;
V_r(&pentry->object.dir_cont.pdir_begin->lock);
break;
case SOCKET_FILE:
case FIFO_FILE:
case BLOCK_FILE:
case CHARACTER_FILE:
//.........这里部分代码省略.........
请发表评论